Load packages

library(tidyverse) # tidy style coding
library(brms) # Bayesian models
library(bayesplot) # pretty bayes visuals
library(tidybayes) # Bayesian aesthetics
library(loo) # to use information criteria in brms models
library(MetBrewer) # colours
library(rcartocolor) # more colours
library(pander) # tables
library(kableExtra) # tables
library(patchwork) # putting plots together
library(DT) # for search- and saveable tables
library(ggdist) # for ribbon plot

Supplementary methods

\(~\)

Table S1. Recipe for food medium used in our experiment. The provided quantities make ~ 1 litre of food.

tibble("Ingredients" = c("Soy flour", "Cornmeal", "Yeast", "Dextrose", "Agar", "Water", "Tegosept", "Acid mix (4 mL orthophosphoric acid, 41 mL propionic acid, 55 mL water to make 100 mL)"),
       "Quantity" = c("20 g", "73 g", "35 g", "75 g", "6 g", "1000 mL", "17 mL", "14 mL")) %>% 
  pander(split.cell = 40, split.table = Inf)
Ingredients Quantity
Soy flour 20 g
Cornmeal 73 g
Yeast 35 g
Dextrose 75 g
Agar 6 g
Water 1000 mL
Tegosept 17 mL
Acid mix (4 mL orthophosphoric acid, 41 mL propionic acid, 55 mL water to make 100 mL) 14 mL

\(~\)

Analysis

\(~\)

Mortality analysis

\(~\)

We conducted single-pair full-sibling crosses to erode heterozygosity across the genome, thereby exposing mutation load. Our proxies for mutation load - extinction rate and productivity decline - may also have been affected by differences in the intensity of interlocus sexual conflict between lineages carrying autosomes with different selection response histories. We specifically designed our experiment to minimise this effect, by enforcing monogamy between all breeding individuals across the extinction assay. However, we cannot discount males carrying male-limited autosomes and/ or control autosomes being more harmful to females than males carrying autosomes with a female-limited selection response history. This might occur because male harm is a by-product of male-male competition, which cannot respond to selection in the female-limited treatments. Furthermore, traits genetically correlated with harm such as activity levels or metabolic rate may be selected in the opposite direction among females, as these traits are highly sexually dimorphic. This may drive the evolution of reduced harm during female-limited evolution.

We observe 135 female (6.2%) and 21 (1%) male mortalities across the 2184 Drosophila vials used during the 20 generations of the experiment (we do not include the 9 final generations observed in Block 1 in this analysis). Male mortality did not occur often enough to provide the power required for formal analysis. We instead focus on modelling female mortality and test whether this is affected by selection response history.

We test this hypothesis to assess whether it is required to censor lineages where the breeding female died in the generation of extinction.

\(~\)

Load in the data

mortality_data <- 
  read_csv("Data/Mortality_data.csv") %>% 
  rowid_to_column("Lineage") %>% 
  pivot_longer(cols = 8:27, names_to = "Generation", values_to = "Female_mortality") %>% 
  mutate(across(1:7, as.factor),
         Generation = as.integer(str_remove(Generation, "Gen_")),
         Male_mortality = Female_mortality,
         Female_mortality = if_else(Female_mortality == "FEMALE" | Female_mortality == "BOTH", 1, 0),
         Male_mortality = if_else(Male_mortality == "MALE" | Male_mortality == "BOTH", 1, 0)) %>% 
  rename(Evolution_treatment = Treatment)

# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'mortality_data')),
      pageLength = 8500
    )
  )
}

my_data_table(mortality_data %>% 
                select(Mother_strain, Father_strain, Cross, Lineage, Block, Generation, Evolution_treatment, Female_mortality, Male_mortality))

\(~\)

Column explanations

Mother strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same Evolution_treatment. This column shows the strain that the founding female of the lineage was derived from.

Father strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same evolution treatment. This column shows the strain that the founding male of the lineage was derived from.

Cross: an identifying ID for each of the 36 combinations of Mother strain and Father strain.

Lineage: lines of flies founded by single inseminated females in generation zero. We generated the next generation of each lineage by crossing a single full-sibling dyad.

Block: the experiment was run in 2 distinct blocks, using flies separated by 9 generations.

Generation: the generation of the extinction assay, ranging from 1 to 20.

Evolution_treatment: the strains had been exposed to one of three evolutionary conditions for 20 generations: a female-limited response to selection, a male-limited response and a control condition where an evolutionary response occurred in both sexes.

Female_mortality: a 0 indicates the female survived until she was removed from the 3-day breeding vial. A 1 indicates she died during this period. Females were 1-4 days old when they entered the breeding vial.

Male_mortality: see Female_mortality, except this column documents male mortality in the breeding vials.

\(~\)

Modelling approach

\(~\)

We fit a binomial model with Evolution_treatment and Block as fixed effects as well as Lineage and Cross as random effects.

mortality_model <- 
  brm(Female_mortality ~ 1 + Evolution_treatment + Block + (1|Cross) + (1|Lineage),
      data = mortality_data %>% filter(Female_mortality != "NA"),
      family = bernoulli,
      prior = c(prior(normal(0, 2), class = Intercept),
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd)),
      iter = 4000, warmup = 2000, chains = 4, cores = 4, seed = 1,
      control = list(adapt_delta = 0.95),
      file = "Fits/mortality_model")

Extract model predictions and plot

# these are specific to block 1, but this doesn't really matter because there is no interaction between treatment and block.

mortality_predictions <-
  mortality_model %>% 
  as_draws_df() %>% 
  mutate(Control = inv_logit_scaled(b_Intercept),
         `Female-limited` = inv_logit_scaled(b_Intercept + b_Evolution_treatmentFemale),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_Evolution_treatmentMale)) %>% 
  select(Control, `Female-limited`, `Male-limited`)
    
# put in easy to plot format

mortality_predictions_long <-
  mortality_predictions %>% 
  pivot_longer(cols = everything(), names_to = "Evolution_treatment", values_to = "Mortality")

# calculate the differences between each treatment

mortality_diff <-
  mortality_predictions %>% 
  mutate(`Control - Male-limited` = Control - `Male-limited`,
         `Male-limited - Female-limited` = `Male-limited` - `Female-limited`,
         `Control - Female-limited` = Control - `Female-limited`) %>% 
  pivot_longer(cols = 4:6, names_to = "Difference_contrast", values_to = "Difference") %>% 
  select(contains("Diff"))

Build Figure S1

mortality_plot <-
  mortality_predictions_long %>% 
  ggplot(aes(x = Mortality, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white", 
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x= "Female mortality (prop.)", y = "Selection response\nhistory") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

mortality_diff_plot <- 
  mortality_diff %>% 
  ggplot(aes(x = Difference, y = fct_relevel(Difference_contrast, "Female - Control", "Male - Female", "Male - Control"))) +
  stat_halfeye(aes(fill = Difference_contrast), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + 
  scale_fill_manual(values = c(carto_pal(7, "Peach")[2], carto_pal(7, "Purp")[1], carto_pal(7, "TealGrn")[1])) +
  geom_vline(xintercept = 0, linetype = 2, colour = "black", size = 1) +
  labs(x = "Diff. in mortality", y = "Treatment contrast") +
  #scale_x_continuous(breaks=seq(-4, 6, 2)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(),
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

mortality_plot / mortality_diff_plot +
  plot_annotation(tag_levels = 'a')

Figure S1. Female mortality is less frequent in lineages with female-limited selection response histories, suggesting that male harm may be less intense in these lineages. Panel a shows the posterior distribution of the number of mortality events as a proportion of the total number of vials that housed lineages throughout the first 20 generations of the extinction assay, split by selection response history. Panel b shows the posterior distribution of the difference between each treatment. The points show the estimated mean, with associated 66 and 95% credible intervals.

\(~\)

To avoid this confounding our measure of mutation load, we can censor extinction events that co-occur with female mortality.

\(~\)

Extinction analysis

Load in the extinction data

\(~\)

extinction_data <- 
  read_csv("Data/Extinction_data.csv") 

# Block 1 runs for 29 generations, while Block 2 only runs for 20. To calculate the censoring variable, we need to split these by Block, mutate the data, then rebind them 

Block_1 <-
  extinction_data %>% 
  filter(Block == "1") %>% 
  # here we create a censoring column. If the family a) escaped or was killed by something unrelated to the experiment or b) survived the 20 generations of the experiment, then we code a value of 1. If the family went extinct, we code a value of 0. This allows us to right censor the data, thereby preserving the information it provides on extinction.
  mutate(across(Gen_1:Gen_29, ~replace_na(.x, "Escape")),
         Censored_alive = if_else(Gen_29 == "YES", 1, 0),
         Censored_escape = if_else(Gen_29 == "Escape", 1, 0),
         Censored = Censored_alive + Censored_escape,
         across(Gen_1:Gen_29, ~if_else(.x == "YES", 1, 0)))
        

Block_2 <-
  extinction_data %>% 
  filter(Block == "2") %>% 
  # here we create a censoring column. If the family a) escaped or was killed by something unrelated to the experiment or b) survived the 20 generations of the experiment, then we code a value of 1. If the family went extinct, we code a value of 0. This allows us to right censor the data, thereby preserving the information it provides on extinction.
  mutate(across(Gen_1:Gen_20, ~replace_na(.x, "Escape")),
         across(Gen_21:Gen_29, ~replace_na(.x, "Not measured")),
         Censored_alive = if_else(Gen_20 == "YES", 1, 0),
         Censored_escape = if_else(Gen_20 == "Escape", 1, 0),
         Censored = Censored_alive + Censored_escape,
         across(Gen_1:Gen_29, ~if_else(.x == "YES", 1, 0)))

# combine the Blocked data back into a single tibble

extinction_data_wrangled <-
  rbind(Block_1, Block_2) %>%
  mutate(across(1:7, as.factor), 
         Gens_to_extinct = Gen_1 + Gen_2 + Gen_3 + Gen_4 + 
           Gen_5 + Gen_6 + Gen_7 + Gen_8 + Gen_9 + Gen_10 + 
           Gen_11 + Gen_12 + Gen_13 + Gen_14 + Gen_15 + Gen_16 + 
           Gen_17 + Gen_18 + Gen_19 + Gen_20 + Gen_21 + Gen_22 + 
           Gen_23 + Gen_24 + Gen_25 + Gen_26 + Gen_27 + Gen_28 + Gen_29 + 1) %>% 
  rename(Evolution_treatment = Treatment, Lineage  = ID) %>% 
  select(Mother_strain, Father_strain, Cross, Lineage, Block, 
         Evolution_treatment, Gens_to_extinct, Gen_1:Gen_29, Censored_alive, 
         Censored_escape, Censored)

# Find the extinctions that co-occur with female mortality

extinction_mortality <-
  left_join(
    extinction_data_wrangled %>% 
      pivot_longer(cols = 8:36, names_to = "Generation", values_to = "Extant") %>% 
      mutate(Generation = as.integer(str_remove(Generation, "Gen_"))),
    
    mortality_data
  ) %>% 
  filter(Extant == 0 & Female_mortality == 1) %>% 
  mutate(Censored_mortality = 1) %>% 
  select(Lineage, Censored_mortality)

extinction_data_wrangled <- left_join(extinction_data_wrangled, extinction_mortality) %>% 
  mutate(Censored_mortality = if_else(is.na(Censored_mortality), 0, 1),
         Censored = Censored + Censored_mortality)

# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'extinction_data')),
      pageLength = 500
    )
  )
}

my_data_table(extinction_data_wrangled)

Column explanations

Mother strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same Evolution_treatment. This column shows the strain that the founding female of the lineage was derived from.

Father strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same evolution treatment. This column shows the strain that the founding male of the lineage was derived from.

Cross: an identifying ID for each of the 36 combinations of Mother strain and Father strain.

Lineage: lines of flies founded by single inseminated females in generation zero. We generated the next generation of each lineage by crossing a single full-sibling dyad.

Block: the experiment was run in 2 distinct blocks, using flies separated by 9 generations. Block 1 ran for 29 generations, whereas Block 2 ran for 20 generations.

Evolution_treatment: the strains had been exposed to one of three evolutionary conditions for 20-29 generations: a female-limited response to selection, a male-limited response and a control condition where an evolutionary response occurred in both sexes.

Gens_to_extinction: the number of generations the lineage survived until it went extinct.

Gen_1:29: a 1 indicates the lineage was extant for the generation in question, while a 0 indicates extinction. Note that we continued propagating surviving lineages from Block 1 until generation 29, which coincided with generation 20 for lineages belonging to the second Block.

Censored: if the lineage 1) ended because flies escaped or were killed by something unrelated to the experiment, 2) went extinct because of breeding female mortality or 3) was extant in the final generation of the experiment, then we coded a value of 1. If the lineage went extinct, we coded a value of 0. This allows us to right censor the data as per the brms syntax, thereby preserving the information these censored cases provide on extinction.

\(~\)

Modelling approach

\(~\)

We fit a weibull survival model to estimate , the extinction rate of the lineages used in our experiment. The weibull model is an extension of an exponential decay model, and includes an additional shape parameter, which allows to vary across generations of inbreeding.

Response variable

Gens_to_extinct is our response - a continuous variable that runs from 1 to 30 generations. Note that we measured extinction up until generation 29 in Block 1 and generation 20 in Block 2. A value of 30 indicates that the lineage was extant at the end of the experiment in Block 1, while a value of 21 indicates this in Block 2. We also include right censoring, to account for lineages extant at the end of the experiment, or that were removed from the experiment by a handling error. Censoring enables the inclusion of this ‘incomplete’ data in the model.

Fixed effects

Evolution_treatment: we include this to test for a causal effect of sex-limited experimental evolution on mutation load.

Block: extinction rate might differ between the blocks we split our experiment up into e.g. because of microvariation in the lab brought about because of a change of season, slight inconsistencies in Drosophila food consistency etc.

Varying/Random effects

Cross: we initiated each lineage by crossing two strains belonging to the same evolution treatment. There were 12 levels of cross nested within evolution treatment, for a total of 36 crosses. We kept lineages from the same Cross and Block in the same column of the Drosophila vial trays, so incuding this variable also controls for micro-environmental variation caused by within-tray position. We used this random effect in our first model.

Mother_strain and Father_strain: Used as an alternative to Cross in our second model. In this case, we fit a multi-membership model, where each lineage simultaneously belongs to two levels of the Cross random effect. That is, each lineage was founded my a mother from \(strain_i\) and a father from \(strain_j\) and they therefore always belong to two levels of strain.

Multi-membership vs single-membership

While the multi-membership approach may initially seem the more powerful of the two random effect structures, we favour the single-membership approach for several reasons. First, our primary aim is to estimate the overall causal effect of evolution treatment on generations to extinction, rather than that of each strain (nested within evolution treatment). Given that we balanced our crossing design so that each strain is equally represented in the experiment, estimation for each strain is not integral. Second, Cross captures nuisance environmental variation that Strain does not. We distributed lineages throughout three Drosophila vial trays by placing lineages from the same cross in the same column. Across the columns we split lineages up by evolution treatment, such that column one contained lineages from the female-limited treatment, column two contained lineages from the male-limited treatment and column three contained lineages from the control treatment. We repeated this pattern until all 36 crosses filled a column. As a strain is used in multiple crosses, it is widely distirbuted throughout the trays and therefore does not capture a location effect like cross does. We are of the opinion that controlling for this environmental variation is of greater importance than strain level differences in mutation load, which both cross and evolution treatment also contain information for.

Finally, we fit both models and use leave one out (LOO) cross validation to formally assess which model has better expected predictive accuracy, both in and out of sample.

Priors

We fit moderately informative priors, with the aim to regularise our posterior estimates and improve model fitting by ruling out non-sensical values.

Note that each of these priors is expressed on the log scale, due to the weibull log link.

\(\alpha\) (the intercepts) ~ Normal(\(\mu\) = 0, \(\sigma\) = 1)

\(\beta\) (the fixed effects) ~ Normal(\(\mu\) = 0, \(\sigma\) = 1)

\(\sigma\) ~ Exponential(1)

\(k\) (The weibull shape parameter) ~ Normal(\(\mu\) = 0, \(\sigma\) = 1)

Fit the models

extinction_model_sm <-
  brm(data = extinction_data_wrangled,
      family = weibull,
      bf(Gens_to_extinct | cens(Censored) ~ 1 + Evolution_treatment + Block + (1|Cross),
         shape ~ 1 + Evolution_treatment + Block),
      # this intercept prior predicts an appropriate starting point for per gen extinction rate on the log scale
      prior = c(prior(gamma(5, 3.5), class = Intercept),  
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd),
                prior(normal(1, 0.5), class = b, dpar = shape)), 
      iter = 8000, warmup = 4000, chains = 4, cores = 4,
      seed = 1, control = list(adapt_delta = .9, max_treedepth = 10),
       file = "Fits/extinction_model_mortality")

extinction_model_sm <- add_criterion(extinction_model_sm, criterion = "loo", moment_match = TRUE)

# the model does not converge when we try and fit a treatment * block interaction

extinction_model_mm <-
  brm(data = extinction_data_wrangled,
      family = weibull,
      bf(Gens_to_extinct | cens(Censored) ~ 1 + Evolution_treatment + Block + (1|mm(Mother_strain, Father_strain)),
      shape ~ 1 + Evolution_treatment + Block),
      # this intercept prior predicts an appropriate starting point for per gen extinction rate on the log scale
      prior = c(prior(gamma(5, 3.5), class = Intercept), 
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd),
                prior(normal(1, 0.5), class = b, dpar = shape)), 
      iter = 8000, warmup = 4000, chains = 4, cores = 4,
      seed = 1, control = list(adapt_delta = 0.9, max_treedepth = 15),
      file = "Fits/extinction_model_mm")

extinction_model_mm <- add_criterion(extinction_model_mm, criterion = "loo")

\(~\)

Model diagnostics

\(~\)

Compare models using LOO, a bayesian information criteria

loo_compare(extinction_model_sm, extinction_model_mm)  %>% 
  kable(digits = 3) %>% 
  kable_styling()
elpd_diff se_diff elpd_loo se_elpd_loo p_loo se_p_loo looic se_looic
extinction_model_sm 0.000 0.000 -1043.238 20.096 23.256 2.797 2086.476 40.191
extinction_model_mm -0.807 2.512 -1044.045 20.131 14.795 2.160 2088.089 40.263

The single-membership model performs slightly better. We present results from this model.

Lets see how the model recapitulates the data

pp_check(extinction_model_sm, type = "hist", ndraws = 11, binwidth = 1) +
  theme_minimal() +
  theme(panel.background = element_blank())

\(~\)

Interpreting model output

\(~\)

We can initially ignore the shape parameter and find the mean rate of extinction, averaged across all generations, using the equation

\(\lambda= \frac{1}{e^\mu}\)

First find distributions of \(\mu\) for each of the three treatments.

inverse_rate_weibull <-
  extinction_model_sm %>% 
  as_draws_df() %>% 
  transmute(`Control B1` = b_Intercept, 
         `Female_limited B1` = b_Intercept + b_Evolution_treatmentFemale,
         `Male_limited B1` = b_Intercept + b_Evolution_treatmentMale,
         `Control B2` = b_Intercept + b_Block2, 
         `Female_limited B2` = b_Intercept + b_Evolution_treatmentFemale + b_Block2,
         `Male_limited B2` = b_Intercept + b_Evolution_treatmentMale + b_Block2)

Now lets plug these distributions into the equation to find mean estimates of \(\lambda\).

  inverse_rate_weibull %>% 
  mutate(across(1:6, ~1 / exp(.x))) %>% 
  mutate(across(everything(), ~mean(.x))) %>% 
  distinct()
## # A tibble: 1 × 6
##   `Control B1` `Female_limited B1` `Male_limited B1` Control B…¹ Femal…² Male_…³
##          <dbl>               <dbl>             <dbl>       <dbl>   <dbl>   <dbl>
## 1        0.141               0.130             0.111       0.120   0.111  0.0947
## # … with abbreviated variable names ¹​`Control B2`, ²​`Female_limited B2`,
## #   ³​`Male_limited B2`

This is the rate of extinction per generation, averaged across all generations. However, the weibull family allows a dynamic rate rather the the constant rate that the exponential constrains it to.

Following this post, the weibull survival function can be found using the following transformation:

\(\lambda= \frac{e^\mu}{\gamma(1 + \frac{1}{k})}\)

where \(k\) is the shape parameter estimated in brms

Then we can find survival at generation \(t\) using

\(S = e^{-(\frac{t}{\lambda})^k}\)

We plug in a vector with 16000 draws from the posterior distribution for 1) of each inheritance treatment and 2) \(k\) the shape parameter to find distributions of the proportion of surviving lineages at each generation.

# Find lambda for the three treatments. 

lambda_weibull <-
  extinction_model_sm %>% 
  as_draws_df() %>% 
  transmute(`Control B1` = b_Intercept, 
            `Female_limited B1` = b_Intercept + b_Evolution_treatmentFemale,
            `Male_limited B1` = b_Intercept + b_Evolution_treatmentMale,
            `Control B2` = b_Intercept + b_Block2, 
            `Female_limited B2` = b_Intercept + b_Evolution_treatmentFemale + b_Block2,
            `Male_limited B2` = b_Intercept + b_Evolution_treatmentMale + b_Block2,
            shape_control_B1 = exp(b_shape_Intercept),
            shape_female_B1 = exp(b_shape_Intercept + b_shape_Evolution_treatmentFemale),
            shape_male_B1 = exp(b_shape_Intercept + b_shape_Evolution_treatmentMale),
            shape_control_B2 = exp(b_shape_Intercept + b_shape_Block2),
            shape_female_B2 = exp(b_shape_Intercept + b_shape_Evolution_treatmentFemale + b_shape_Block2),
            shape_male_B2 = exp(b_shape_Intercept + b_shape_Evolution_treatmentMale + b_shape_Block2)) %>% 
  mutate(Control_lambda_B1 = exp(`Control B1`) / gamma(1 + 1/shape_control_B1),
         Female_lambda_B1 = exp(`Female_limited B1`) / gamma(1 + 1/shape_female_B1),
         Male_lambda_B1 = exp(`Male_limited B1`) / gamma(1 + 1/shape_male_B1),
         Control_lambda_B2 = exp(`Control B2`) / gamma(1 + 1/shape_control_B2),
         Female_lambda_B2 = exp(`Female_limited B2`) / gamma(1 + 1/shape_female_B2),
         Male_lambda_B2 = exp(`Male_limited B2`) / gamma(1 + 1/shape_male_B2)) %>% 
  select(contains(c("lambda", "shape")))

# Now find survival proportion at generations 1-29

Weibull_survival_curve <- 
  lambda_weibull %>% 
  mutate(#Block 1
    Control_0_B1  = exp(-(0/Control_lambda_B1)^shape_control_B1),  
    Control_1_B1  = exp(-(1/Control_lambda_B1)^shape_control_B1),
    Control_2_B1  = exp(-(2/Control_lambda_B1)^shape_control_B1),
    Control_3_B1  = exp(-(3/Control_lambda_B1)^shape_control_B1),
    Control_4_B1  = exp(-(4/Control_lambda_B1)^shape_control_B1),
    Control_5_B1  = exp(-(5/Control_lambda_B1)^shape_control_B1),
    Control_6_B1  = exp(-(6/Control_lambda_B1)^shape_control_B1),
    Control_7_B1  = exp(-(7/Control_lambda_B1)^shape_control_B1),
    Control_8_B1 = exp(-(8/Control_lambda_B1)^shape_control_B1),
    Control_9_B1 = exp(-(9/Control_lambda_B1)^shape_control_B1),
    Control_10_B1 = exp(-(10/Control_lambda_B1)^shape_control_B1),
    Control_11_B1 = exp(-(11/Control_lambda_B1)^shape_control_B1),
    Control_12_B1 = exp(-(12/Control_lambda_B1)^shape_control_B1),
    Control_13_B1 = exp(-(13/Control_lambda_B1)^shape_control_B1),
    Control_14_B1 = exp(-(14/Control_lambda_B1)^shape_control_B1),
    Control_15_B1 = exp(-(15/Control_lambda_B1)^shape_control_B1),
    Control_16_B1 = exp(-(16/Control_lambda_B1)^shape_control_B1),
    Control_17_B1 = exp(-(17/Control_lambda_B1)^shape_control_B1),
    Control_18_B1 = exp(-(18/Control_lambda_B1)^shape_control_B1),
    Control_19_B1 = exp(-(19/Control_lambda_B1)^shape_control_B1),
    Control_20_B1 = exp(-(20/Control_lambda_B1)^shape_control_B1),
    Control_21_B1 = exp(-(21/Control_lambda_B1)^shape_control_B1),
    Control_22_B1 = exp(-(22/Control_lambda_B1)^shape_control_B1),
    Control_23_B1 = exp(-(23/Control_lambda_B1)^shape_control_B1),
    Control_24_B1 = exp(-(24/Control_lambda_B1)^shape_control_B1),
    Control_25_B1 = exp(-(25/Control_lambda_B1)^shape_control_B1),
    Control_26_B1 = exp(-(26/Control_lambda_B1)^shape_control_B1),
    Control_27_B1 = exp(-(27/Control_lambda_B1)^shape_control_B1),
    Control_28_B1 = exp(-(28/Control_lambda_B1)^shape_control_B1),
    Control_29_B1 = exp(-(29/Control_lambda_B1)^shape_control_B1),
    Female_0_B1  = exp(-(0/Female_lambda_B1)^shape_female_B1),
    Female_1_B1  = exp(-(1/Female_lambda_B1)^shape_female_B1),
    Female_2_B1  = exp(-(2/Female_lambda_B1)^shape_female_B1),
    Female_3_B1  = exp(-(3/Female_lambda_B1)^shape_female_B1),
    Female_4_B1  = exp(-(4/Female_lambda_B1)^shape_female_B1),
    Female_5_B1  = exp(-(5/Female_lambda_B1)^shape_female_B1),
    Female_6_B1  = exp(-(6/Female_lambda_B1)^shape_female_B1),
    Female_7_B1  = exp(-(7/Female_lambda_B1)^shape_female_B1),
    Female_8_B1  = exp(-(8/Female_lambda_B1)^shape_female_B1),
    Female_9_B1  = exp(-(9/Female_lambda_B1)^shape_female_B1),
    Female_10_B1  = exp(-(10/Female_lambda_B1)^shape_female_B1),
    Female_11_B1  = exp(-(11/Female_lambda_B1)^shape_female_B1),
    Female_12_B1  = exp(-(12/Female_lambda_B1)^shape_female_B1),
    Female_13_B1  = exp(-(13/Female_lambda_B1)^shape_female_B1),
    Female_14_B1  = exp(-(14/Female_lambda_B1)^shape_female_B1),
    Female_15_B1  = exp(-(15/Female_lambda_B1)^shape_female_B1),
    Female_16_B1  = exp(-(16/Female_lambda_B1)^shape_female_B1),
    Female_17_B1  = exp(-(17/Female_lambda_B1)^shape_female_B1),
    Female_18_B1  = exp(-(18/Female_lambda_B1)^shape_female_B1),
    Female_19_B1  = exp(-(19/Female_lambda_B1)^shape_female_B1),
    Female_20_B1  = exp(-(20/Female_lambda_B1)^shape_female_B1),
    Female_21_B1 = exp(-(21/Female_lambda_B1)^shape_female_B1),
    Female_22_B1 = exp(-(22/Female_lambda_B1)^shape_female_B1),
    Female_23_B1 = exp(-(23/Female_lambda_B1)^shape_female_B1),
    Female_24_B1 = exp(-(24/Female_lambda_B1)^shape_female_B1),
    Female_25_B1 = exp(-(25/Female_lambda_B1)^shape_female_B1),
    Female_26_B1 = exp(-(26/Female_lambda_B1)^shape_female_B1),
    Female_27_B1 = exp(-(27/Female_lambda_B1)^shape_female_B1),
    Female_28_B1 = exp(-(28/Female_lambda_B1)^shape_female_B1),
    Female_29_B1 = exp(-(29/Female_lambda_B1)^shape_female_B1),
    Male_0_B1     = exp(-(0/Male_lambda_B1)^shape_male_B1),
    Male_1_B1     = exp(-(1/Male_lambda_B1)^shape_male_B1),
    Male_2_B1     = exp(-(2/Male_lambda_B1)^shape_male_B1),
    Male_3_B1     = exp(-(3/Male_lambda_B1)^shape_male_B1),
    Male_4_B1     = exp(-(4/Male_lambda_B1)^shape_male_B1),
    Male_5_B1     = exp(-(5/Male_lambda_B1)^shape_male_B1),
    Male_6_B1     = exp(-(6/Male_lambda_B1)^shape_male_B1),
    Male_7_B1     = exp(-(7/Male_lambda_B1)^shape_male_B1),
    Male_8_B1     = exp(-(8/Male_lambda_B1)^shape_male_B1),
    Male_9_B1     = exp(-(9/Male_lambda_B1)^shape_male_B1),
    Male_10_B1    = exp(-(10/Male_lambda_B1)^shape_male_B1),
    Male_11_B1    = exp(-(11/Male_lambda_B1)^shape_male_B1),
    Male_12_B1    = exp(-(12/Male_lambda_B1)^shape_male_B1),
    Male_13_B1    = exp(-(13/Male_lambda_B1)^shape_male_B1),
    Male_14_B1    = exp(-(14/Male_lambda_B1)^shape_male_B1),
    Male_15_B1    = exp(-(15/Male_lambda_B1)^shape_male_B1),
    Male_16_B1    = exp(-(16/Male_lambda_B1)^shape_male_B1),
    Male_17_B1    = exp(-(17/Male_lambda_B1)^shape_male_B1),
    Male_18_B1    = exp(-(18/Male_lambda_B1)^shape_male_B1),
    Male_19_B1    = exp(-(19/Male_lambda_B1)^shape_male_B1),
    Male_20_B1    = exp(-(20/Male_lambda_B1)^shape_male_B1),
    Male_21_B1 = exp(-(21/Male_lambda_B1)^shape_male_B1),
    Male_22_B1 = exp(-(22/Male_lambda_B1)^shape_male_B1),
    Male_23_B1 = exp(-(23/Male_lambda_B1)^shape_male_B1),
    Male_24_B1 = exp(-(24/Male_lambda_B1)^shape_male_B1),
    Male_25_B1 = exp(-(25/Male_lambda_B1)^shape_male_B1),
    Male_26_B1 = exp(-(26/Male_lambda_B1)^shape_male_B1),
    Male_27_B1 = exp(-(27/Male_lambda_B1)^shape_male_B1),
    Male_28_B1 = exp(-(28/Male_lambda_B1)^shape_male_B1),
    Male_29_B1 = exp(-(29/Male_lambda_B1)^shape_male_B1),
    # Block 2
    Control_0_B2  = exp(-(0/Control_lambda_B2)^shape_control_B2),  
    Control_1_B2  = exp(-(1/Control_lambda_B2)^shape_control_B2),
    Control_2_B2  = exp(-(2/Control_lambda_B2)^shape_control_B2),
    Control_3_B2  = exp(-(3/Control_lambda_B2)^shape_control_B2),
    Control_4_B2  = exp(-(4/Control_lambda_B2)^shape_control_B2),
    Control_5_B2  = exp(-(5/Control_lambda_B2)^shape_control_B2),
    Control_6_B2  = exp(-(6/Control_lambda_B2)^shape_control_B2),
    Control_7_B2  = exp(-(7/Control_lambda_B2)^shape_control_B2),
    Control_8_B2 = exp(-(8/Control_lambda_B2)^shape_control_B2),
    Control_9_B2 = exp(-(9/Control_lambda_B2)^shape_control_B2),
    Control_10_B2 = exp(-(10/Control_lambda_B2)^shape_control_B2),
    Control_11_B2 = exp(-(11/Control_lambda_B2)^shape_control_B2),
    Control_12_B2 = exp(-(12/Control_lambda_B2)^shape_control_B2),
    Control_13_B2 = exp(-(13/Control_lambda_B2)^shape_control_B2),
    Control_14_B2 = exp(-(14/Control_lambda_B2)^shape_control_B2),
    Control_15_B2 = exp(-(15/Control_lambda_B2)^shape_control_B2),
    Control_16_B2 = exp(-(16/Control_lambda_B2)^shape_control_B2),
    Control_17_B2 = exp(-(17/Control_lambda_B2)^shape_control_B2),
    Control_18_B2 = exp(-(18/Control_lambda_B2)^shape_control_B2),
    Control_19_B2 = exp(-(19/Control_lambda_B2)^shape_control_B2),
    Control_20_B2 = exp(-(20/Control_lambda_B2)^shape_control_B2),
    Control_21_B2 = exp(-(21/Control_lambda_B2)^shape_control_B2),
    Control_22_B2 = exp(-(22/Control_lambda_B2)^shape_control_B2),
    Control_23_B2 = exp(-(23/Control_lambda_B2)^shape_control_B2),
    Control_24_B2 = exp(-(24/Control_lambda_B2)^shape_control_B2),
    Control_25_B2 = exp(-(25/Control_lambda_B2)^shape_control_B2),
    Control_26_B2 = exp(-(26/Control_lambda_B2)^shape_control_B2),
    Control_27_B2 = exp(-(27/Control_lambda_B2)^shape_control_B2),
    Control_28_B2 = exp(-(28/Control_lambda_B2)^shape_control_B2),
    Control_29_B2 = exp(-(29/Control_lambda_B2)^shape_control_B2),
    Female_0_B2  = exp(-(0/Female_lambda_B2)^shape_female_B2),
    Female_1_B2  = exp(-(1/Female_lambda_B2)^shape_female_B2),
    Female_2_B2  = exp(-(2/Female_lambda_B2)^shape_female_B2),
    Female_3_B2  = exp(-(3/Female_lambda_B2)^shape_female_B2),
    Female_4_B2  = exp(-(4/Female_lambda_B2)^shape_female_B2),
    Female_5_B2  = exp(-(5/Female_lambda_B2)^shape_female_B2),
    Female_6_B2  = exp(-(6/Female_lambda_B2)^shape_female_B2),
    Female_7_B2  = exp(-(7/Female_lambda_B2)^shape_female_B2),
    Female_8_B2  = exp(-(8/Female_lambda_B2)^shape_female_B2),
    Female_9_B2  = exp(-(9/Female_lambda_B2)^shape_female_B2),
    Female_10_B2  = exp(-(10/Female_lambda_B2)^shape_female_B2),
    Female_11_B2  = exp(-(11/Female_lambda_B2)^shape_female_B2),
    Female_12_B2  = exp(-(12/Female_lambda_B2)^shape_female_B2),
    Female_13_B2  = exp(-(13/Female_lambda_B2)^shape_female_B2),
    Female_14_B2  = exp(-(14/Female_lambda_B2)^shape_female_B2),
    Female_15_B2  = exp(-(15/Female_lambda_B2)^shape_female_B2),
    Female_16_B2  = exp(-(16/Female_lambda_B2)^shape_female_B2),
    Female_17_B2  = exp(-(17/Female_lambda_B2)^shape_female_B2),
    Female_18_B2  = exp(-(18/Female_lambda_B2)^shape_female_B2),
    Female_19_B2  = exp(-(19/Female_lambda_B2)^shape_female_B2),
    Female_20_B2  = exp(-(20/Female_lambda_B2)^shape_female_B2),
    Female_21_B2 = exp(-(21/Female_lambda_B2)^shape_female_B2),
    Female_22_B2 = exp(-(22/Female_lambda_B2)^shape_female_B2),
    Female_23_B2 = exp(-(23/Female_lambda_B2)^shape_female_B2),
    Female_24_B2 = exp(-(24/Female_lambda_B2)^shape_female_B2),
    Female_25_B2 = exp(-(25/Female_lambda_B2)^shape_female_B2),
    Female_26_B2 = exp(-(26/Female_lambda_B2)^shape_female_B2),
    Female_27_B2 = exp(-(27/Female_lambda_B2)^shape_female_B2),
    Female_28_B2 = exp(-(28/Female_lambda_B2)^shape_female_B2),
    Female_29_B2 = exp(-(29/Female_lambda_B2)^shape_female_B2),
    Male_0_B2     = exp(-(0/Male_lambda_B2)^shape_male_B2),
    Male_1_B2     = exp(-(1/Male_lambda_B2)^shape_male_B2),
    Male_2_B2     = exp(-(2/Male_lambda_B2)^shape_male_B2),
    Male_3_B2     = exp(-(3/Male_lambda_B2)^shape_male_B2),
    Male_4_B2     = exp(-(4/Male_lambda_B2)^shape_male_B2),
    Male_5_B2     = exp(-(5/Male_lambda_B2)^shape_male_B2),
    Male_6_B2     = exp(-(6/Male_lambda_B2)^shape_male_B2),
    Male_7_B2     = exp(-(7/Male_lambda_B2)^shape_male_B2),
    Male_8_B2     = exp(-(8/Male_lambda_B2)^shape_male_B2),
    Male_9_B2     = exp(-(9/Male_lambda_B2)^shape_male_B2),
    Male_10_B2    = exp(-(10/Male_lambda_B2)^shape_male_B2),
    Male_11_B2    = exp(-(11/Male_lambda_B2)^shape_male_B2),
    Male_12_B2    = exp(-(12/Male_lambda_B2)^shape_male_B2),
    Male_13_B2    = exp(-(13/Male_lambda_B2)^shape_male_B2),
    Male_14_B2    = exp(-(14/Male_lambda_B2)^shape_male_B2),
    Male_15_B2    = exp(-(15/Male_lambda_B2)^shape_male_B2),
    Male_16_B2    = exp(-(16/Male_lambda_B2)^shape_male_B2),
    Male_17_B2    = exp(-(17/Male_lambda_B2)^shape_male_B2),
    Male_18_B2    = exp(-(18/Male_lambda_B2)^shape_male_B2),
    Male_19_B2    = exp(-(19/Male_lambda_B2)^shape_male_B2),
    Male_20_B2    = exp(-(20/Male_lambda_B2)^shape_male_B2),
    Male_21_B2 = exp(-(21/Male_lambda_B2)^shape_male_B2),
    Male_22_B2 = exp(-(22/Male_lambda_B2)^shape_male_B2),
    Male_23_B2 = exp(-(23/Male_lambda_B2)^shape_male_B2),
    Male_24_B2 = exp(-(24/Male_lambda_B2)^shape_male_B2),
    Male_25_B2 = exp(-(25/Male_lambda_B2)^shape_male_B2),
    Male_26_B2 = exp(-(26/Male_lambda_B2)^shape_male_B2),
    Male_27_B2 = exp(-(27/Male_lambda_B2)^shape_male_B2),
    Male_28_B2 = exp(-(28/Male_lambda_B2)^shape_male_B2),
    Male_29_B2 = exp(-(29/Male_lambda_B2)^shape_male_B2)) %>% 
  select(-c(contains(c("shape", "lambda"))))

Weibull_extinction_estimates_long <-
  Weibull_survival_curve %>% 
  pivot_longer(cols = everything(), names_to = "Evolution treatment", values_to = "Prop_lineages_surviving") %>% 
  separate(`Evolution treatment`, into = c("Evolution treatment", "Generation", "Block"), sep = "_") %>% 
    mutate(`Evolution treatment` = case_when(
    `Evolution treatment` == "Female" ~ "Female-limited",
    `Evolution treatment` == "Male" ~ "Male-limited",
    `Evolution treatment` == "Control" ~ "Control"
  ))

\(~\)

Create Figure 1

Make panel a of Figure 1

# Block 1

weibull_surv_plot_B1 <- 
  Weibull_extinction_estimates_long %>% 
  filter(Block == "B1") %>% 
  group_by(`Evolution treatment`, Generation) %>% 
  tidybayes::median_qi(Prop_lineages_surviving, .width = 0.5) %>% 
  mutate(Generation = as.numeric(Generation)) %>% 
  arrange(Generation) %>% 
  # plot!
  ggplot(aes(x = Generation)) +
  geom_ribbon(aes(ymin = .lower, ymax = .upper, fill = `Evolution treatment`),
              alpha = 1/2) +
  geom_line(aes(y = Prop_lineages_surviving, color = `Evolution treatment`), linetype =5, linewidth = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_color_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_x_continuous(breaks = c(0, 5, 10, 15, 20, 25, 30), expand = expansion(mult = c(0.01, 0.01))) +
  scale_y_continuous(breaks = c(0, 0.25, .5, 0.75, 1), limits = 0:1, expand = expansion(mult = c(0.01, 0.01))) +
  labs(x = "Generations of inbreeding", y = "Proportion of surving lineages", fill = "Selection response\nhistory") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.background = element_rect(fill='transparent'), #transparent legend bg
        legend.box.background = element_rect(fill='transparent', colour = 'transparent'), #transparent legend panel
        legend.position = c(.95, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6),
        text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11))

We can also plot the mean generations until extinction for each evolution treatment. Some data wrangling is first needed.

new_data <- expand_grid(
  Evolution_treatment = extinction_data_wrangled$Evolution_treatment,
  Block = 1:2) %>% 
  distinct(Evolution_treatment, Block) %>%
  mutate(key = paste("V", 1:n(), sep = ""))

weibull_estimates <- 
  fitted(extinction_model_sm, newdata = new_data,
         re_formula = NA, summary = F) %>% 
  as_tibble() %>% 
  rename(`Female-limited_1` = V1, `Female-limited_2` = V2, `Male-limited_1` = V3, `Male-limited_2` = V4, Control_1 = V5, Control_2 = V6)

mean_weibull_estimates <- 
  weibull_estimates %>% 
  pivot_longer(cols = 1:6, names_to = "Evolution treatment", values_to = "generations") %>% 
  separate(col = `Evolution treatment`, into = c("Evolution treatment", "Block"), sep = "_")


# calculate contrasts

weibull_contrasts_B1 <-
  weibull_estimates %>% 
  mutate(`Female - Control` = `Female-limited_1` - Control_1,
         `Male - Female` = `Male-limited_1` - `Female-limited_1`,
         `Male - Control` = `Male-limited_1` - Control_1) %>% 
  select(-c(`Male-limited_1`, Control_1, `Female-limited_1`,
            `Male-limited_2`, Control_2, `Female-limited_2`)) %>% 
  pivot_longer(cols = 1:3, names_to = "Contrast", values_to = "generation_diff")

weibull_contrasts_B2 <-
  weibull_estimates %>% 
  mutate(`Female - Control` = `Female-limited_2` - Control_2,
         `Male - Female` = `Male-limited_2` - `Female-limited_2`,
         `Male - Control` = `Male-limited_2` - Control_2) %>% 
  select(-c(`Male-limited_1`, Control_1, `Female-limited_1`,
            `Male-limited_2`, Control_2, `Female-limited_2`)) %>% 
  pivot_longer(cols = 1:3, names_to = "Contrast", values_to = "generation_diff")

Create panels b and c of Figure 1

# plot the means

# block 1

ext_p1_B1 <- 
  mean_weibull_estimates %>% 
  filter(Block == "1") %>% 
  ggplot(aes(x = generations, y = `Evolution treatment`)) +
  stat_halfeye(aes(fill = `Evolution treatment`), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals + # width indicates the uncertainty intervals: here we have 66% and 95% intervals+
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x = "Mean generations till extinction", y = "Selection response history") +
  scale_x_continuous(breaks=seq(4, 12, 1)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(), 
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

# plot the contrasts

ext_p2_B1 <- 
  weibull_contrasts_B1 %>% 
  ggplot(aes(x = generation_diff, y = fct_relevel(Contrast, "Female - Control", "Male - Female", "Male - Control"))) +
  stat_halfeye(aes(fill = Contrast), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + 
  scale_fill_manual(values = c(carto_pal(7, "Peach")[2], carto_pal(7, "Purp")[1], carto_pal(7, "TealGrn")[1])) +
  geom_vline(xintercept = 0, linetype = 2, colour = "black", size = 1) +
  labs(x = "Diff. in generations till extinction", y = "Treatment contrast") +
  scale_x_continuous(breaks=seq(-4, 6, 2)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(),
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

We can also estimate the difference between evolutionary treatments in the proportion of lineages extant in each generation. Below we calculate each contrast and make panels d, e and f

# Block 1

Difference_gens_B1 <-
  Weibull_survival_curve %>% 
  select(contains("B1")) %>% 
  mutate(G1_diff.c = Male_1_B1 - Control_1_B1,
         G1_diff.f = Male_1_B1 - Female_1_B1,
         G1_diff.fc = Female_1_B1 - Control_1_B1,
         G2_diff.c = Male_2_B1 - Control_2_B1,
         G2_diff.f = Male_2_B1 - Female_2_B1,
         G2_diff.fc = Female_2_B1 - Control_2_B1,
         G3_diff.c = Male_3_B1 - Control_3_B1,
         G3_diff.f = Male_3_B1 - Female_3_B1,
         G3_diff.fc = Female_3_B1 - Control_3_B1,
         G4_diff.c = Male_4_B1 - Control_4_B1,
         G4_diff.f = Male_4_B1 - Female_4_B1,
         G4_diff.fc = Female_4_B1 - Control_4_B1,
         G5_diff.c = Male_5_B1 - Control_5_B1,
         G5_diff.f = Male_5_B1 - Female_5_B1,
         G5_diff.fc = Female_5_B1 - Control_5_B1,
         G6_diff.c = Male_6_B1 - Control_6_B1,
         G6_diff.f = Male_6_B1 - Female_6_B1,
         G6_diff.fc = Female_6_B1 - Control_6_B1,
         G7_diff.c = Male_7_B1 - Control_7_B1,
         G7_diff.f = Male_7_B1 - Female_7_B1,
         G7_diff.fc = Female_7_B1 - Control_7_B1,
         G8_diff.c = Male_8_B1 - Control_8_B1,
         G8_diff.f = Male_8_B1 - Female_8_B1,
         G8_diff.fc = Female_8_B1 - Control_8_B1,
         G9_diff.c = Male_9_B1 - Control_9_B1,
         G9_diff.f = Male_9_B1 - Female_9_B1,
         G9_diff.fc = Female_9_B1 - Control_9_B1,
         G10_diff.c = Male_10_B1 - Control_10_B1,
         G10_diff.f = Male_10_B1 - Female_10_B1,
         G10_diff.fc = Female_10_B1 - Control_10_B1,
         G11_diff.c = Male_11_B1 - Control_11_B1,
         G11_diff.f = Male_11_B1 - Female_11_B1,
         G11_diff.fc = Female_11_B1 - Control_11_B1,
         G12_diff.c = Male_12_B1 - Control_12_B1,
         G12_diff.f = Male_12_B1 - Female_12_B1,
         G12_diff.fc = Female_12_B1 - Control_12_B1,
         G13_diff.c = Male_13_B1 - Control_13_B1,
         G13_diff.f = Male_13_B1 - Female_13_B1,
         G13_diff.fc = Female_13_B1 - Control_13_B1,
         G14_diff.c = Male_14_B1 - Control_14_B1,
         G14_diff.f = Male_14_B1 - Female_14_B1,
         G14_diff.fc = Female_14_B1 - Control_14_B1,
         G15_diff.c = Male_15_B1 - Control_15_B1,
         G15_diff.f = Male_15_B1 - Female_15_B1,
         G15_diff.fc = Female_15_B1 - Control_15_B1,
         G16_diff.c = Male_16_B1 - Control_16_B1,
         G16_diff.f = Male_16_B1 - Female_16_B1,
         G16_diff.fc = Female_16_B1 - Control_16_B1,
         G17_diff.c = Male_17_B1 - Control_17_B1,
         G17_diff.f = Male_17_B1 - Female_17_B1,
         G17_diff.fc = Female_17_B1 - Control_17_B1,
         G18_diff.c = Male_18_B1 - Control_18_B1,
         G18_diff.f = Male_18_B1 - Female_18_B1,
         G18_diff.fc = Female_18_B1 - Control_18_B1,
         G19_diff.c = Male_19_B1 - Control_19_B1,
         G19_diff.f = Male_19_B1 - Female_19_B1,
         G19_diff.fc = Female_19_B1 - Control_19_B1,
         G20_diff.c = Male_20_B1 - Control_20_B1,
         G20_diff.f = Male_20_B1 - Female_20_B1,
         G20_diff.fc = Female_20_B1 - Control_20_B1,
         G21_diff.c = Male_21_B1 - Control_21_B1,
         G21_diff.f = Male_21_B1 - Female_21_B1,
         G21_diff.fc = Female_21_B1 - Control_21_B1,
         G22_diff.c = Male_22_B1 - Control_22_B1,
         G22_diff.f = Male_22_B1 - Female_22_B1,
         G22_diff.fc = Female_22_B1 - Control_22_B1,
         G23_diff.c = Male_23_B1 - Control_23_B1,
         G23_diff.f = Male_23_B1 - Female_23_B1,
         G23_diff.fc = Female_23_B1 - Control_23_B1,
         G24_diff.c = Male_24_B1 - Control_24_B1,
         G24_diff.f = Male_24_B1 - Female_24_B1,
         G24_diff.fc = Female_24_B1 - Control_24_B1,
         G25_diff.c = Male_25_B1 - Control_25_B1,
         G25_diff.f = Male_25_B1 - Female_25_B1,
         G25_diff.fc = Female_25_B1 - Control_25_B1,
         G26_diff.c = Male_26_B1 - Control_26_B1,
         G26_diff.f = Male_26_B1 - Female_26_B1,
         G26_diff.fc = Female_26_B1 - Control_26_B1,
         G27_diff.c = Male_27_B1 - Control_27_B1,
         G27_diff.f = Male_27_B1 - Female_27_B1,
         G27_diff.fc = Female_27_B1 - Control_27_B1,
         G28_diff.c = Male_28_B1 - Control_28_B1,
         G28_diff.f = Male_28_B1 - Female_28_B1,
         G28_diff.fc = Female_28_B1 - Control_28_B1,
         G29_diff.c = Male_2_B1 - Control_29_B1,
         G29_diff.f = Male_29_B1 - Female_29_B1,
         G29_diff.fc = Female_29_B1 - Control_29_B1) %>% 
  select(starts_with("G")) %>% 
  pivot_longer(cols = everything(), names_to = "Difference contrast", values_to = "survival_diff") %>% 
  separate(`Difference contrast`, into = c("Generation", "Difference contrast"), sep = "_") %>% 
  mutate(Generation = as.numeric(str_remove(Generation, "G")))


# Make the three plots

Leaf_plot_mc_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.c") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProp. surv lineages",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8)) 

Leaf_plot_mf_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.f") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProp. surv lineages",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_fc_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.fc") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProp. surv lineages",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Combine the 6 panels

(weibull_surv_plot_B1 / (ext_p1_B1 + ext_p2_B1)) / (Leaf_plot_mc_B1 + Leaf_plot_mf_B1 + Leaf_plot_fc_B1) +
  plot_annotation(tag_levels = 'a')

Figure 1. …

\(~\)

Productivity analysis

\(~\)

We have several hypotheses that we test with the productivity data. First, productivity should be negatively correlated with the number of generations inbreeding occurs, due to inbreeding depression. As mentioned above, this effect should be strongest in the first ~10 generations of the experiment, during which full-sibling inbreeding should have the largest effects on genome wide heterozygosity. After this point, the inbreeding coefficient will be 0.89, while over the next 10 generations it should only increase by a further 0.1 to 0.99. Hence, we expect productivity to stabilise between the 10th and 20th generations, assuming the lineage is still extant. Second, lineages carrying autosomes that have responded to selection on males should exhibit a smaller drop in productivity compared with lineages caryring the female-adapted or control autosomes, because they have a history of stronger selection that should, in theory, have purged the genome of recessive deleterious alleles.

Load in the data

data <-
  read_csv("Data/Productivity_data.csv")

Productivity_data <- 
  left_join(
    data,
    
    data %>% 
      distinct(Cross, Replicate) %>% 
      rowid_to_column("Lineage")
  ) %>% 
  select(Lineage, everything()) %>% 
  mutate(across(1:7, as.factor),
         Collection_window_offspring = Female_offspring + Male_offspring,
         Pre_window_offspring = Pre_window_female_offspring + Pre_window_male_offspring,
         Total_female_offspring = Female_offspring + Pre_window_female_offspring,
         Total_male_offspring = Male_offspring + Pre_window_male_offspring,
         Total_offspring = Total_female_offspring + Total_male_offspring) %>% 
  # In one generation of the experiment (b1 = G24 & B2 = G15) sibling pairs were setup a day early and removed from their vials at the regular time, meaning that they had an extra day to produce offspring. To correct for this we multiply offspring counts by 0.75.
  mutate(Collection_window_offspring = if_else(Count_conditions == "Extra day", 
                                               round(Collection_window_offspring * 0.75),  Collection_window_offspring),
         # note that because everything is moved a day early, pre-window offspring counts will still be inflated even after this correction
         Pre_window_offspring = if_else(Count_conditions == "Extra day", 
                                               round(Pre_window_offspring * 0.75),  Pre_window_offspring))
  
# Make a tibble that only includes data from the first 20 generations of the experiment (Block 1 ran for 29 gens, while Block 2 ran for 20). Then remove lineage's that at some point were lost because of handling errors and thus do not have data from that generation onwards.

Productivity_data_clean <-
  left_join(
    Productivity_data %>% 
      filter(Generation < 21) %>% 
      filter(Collection_window_offspring != "NA") %>% # remove NA values
      group_by(Lineage, Block) %>% # these remaining lines remove lineage's that had an NA value 
      count() %>% 
      ungroup() %>% 
      filter(n == 20), # remove lineage's that have NA values for productivity in at least one generation
    
    Productivity_data) %>% 
  filter(Generation < 21) # only include data collected on the first 20 generations of inbreeding (block 2's endpoint)

# We also include a column that specifies if a lineage was extinct. This means we can easily remove 0 values from the data if required. We can use the `extinction_data_wrangled$Gens_to_extinct` column to help us here. 

Productivity_data_clean_2 <-
  left_join(
    Productivity_data_clean,  
    extinction_data_wrangled %>% 
      select(Lineage, Gens_to_extinct)
  ) %>% 
  mutate(Extinct = if_else(Generation > Gens_to_extinct, "Yes", "No"))

# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'Productivity_data_clean_2')),
      pageLength = 8500
    )
  )
}

my_data_table(Productivity_data_clean_2 %>% 
                select(Mother_strain, Father_strain, Cross, Lineage, Block, Generation, Treatment, Extinct, Count_conditions, Female_offspring, Male_offspring, Collection_window_offspring, Pre_window_female_offspring, Pre_window_male_offspring, Pre_window_offspring, Total_female_offspring, Total_male_offspring, Total_offspring))

Column explanations

Mother strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same Evolution_treatment. This column shows the strain that the founding female of the lineage was derived from.

Father strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same evolution treatment. This column shows the strain that the founding male of the lineage was derived from.

Cross: an identifying ID for each of the 36 combinations of Mother strain and Father strain.

Lineage: lines of flies founded by single inseminated females in generation zero. We generated the next generation of each lineage by crossing a single full-sibling dyad.

Block: the experiment was run in 2 distinct blocks, using flies separated by 9 generations. Block 1 ran for 29 generations, whereas Block 2 ran for 20 generations.

Generation: the generation of the extinction assay, ranging from 1 to 20.

Evolution_treatment: the strains had been exposed to one of three evolutionary conditions for 20-29 generations: a female-limited response to selection, a male-limited response and a control condition where an evolutionary response occurred in both sexes.

Extinct: specifies whether the lineage was extinct in this generation.

Count_conditions: Normal indicates that the breeding window lasted the standard three days. Extra day indicates the breeding pair were left in the vial for an extra day. This occurred during generation 15 of the second experimental block.

Female_offspring: the number of adult females produced by the breeding pair that eclosed during the four-day collection window

Male_offspring: as above, but for male offspring.

Collection_window_offspring: the sum of Female_offspring and Male_offspring.

Pre_window_female_offspring: females progeny that eclosed prior to the collection window opening.

Pre_window_male_offspring: as above, but for male offspring.

Pre_window_offspring: the sum of Pre_window_female_offspring and Pre_window_male_offspring.

Total_female_offspring: the sum of Female_offspring and Pre_window_female_offspring.

Total_male_offspring: as above, but for male offspring.

Total_offspring: the total number of offspring produced, summed across the sexes and the pre-window and within-window collections.

\(~\)

Do we observe inbreeding depression?

\(~\)

Let’s plot the raw data to get an idea.

# Collection window plot

point_plot_1 <-
  Productivity_data_clean %>%
  ggplot(aes(x = Generation, y = Collection_window_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.25) +
  geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7]) +
  geom_smooth(data = Productivity_data_clean_2 %>% filter(Extinct == "No"), size = 1.5, colour = met.brewer("OKeeffe2")[6]) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20)) +
  labs(y = "Collection window\noffspring production", x = "Generation of inbreeding") +
  theme(text = element_text(size = 14))

# Total productivity plot

point_plot_2 <-
  Productivity_data %>% 
  ggplot(aes(x = Generation, y = Total_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.25) +
  geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7]) +
  geom_smooth(data = Productivity_data_clean_2 %>% filter(Extinct == "No"), size = 1.5, colour = met.brewer("OKeeffe2")[6]) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20)) +
  labs(y = "Total offspring production", x = "Generation of inbreeding") +
  theme(text = element_text(size = 14))

point_plot_1 / point_plot_2

\(~\)

Testing for our casual effect

\(~\)

Modelling approach

As mentioned above, we have strong expectations for how full-sibling inbreeding should affect productivity. Decreasing genome-wide heterozygosity and the expression of recessive deleterious alleles that comes with this should follow a pattern of exponential decay. This non-linear process can be modelled using the brms non-linear syntax.

Here we model the productivity at generation \(t\) via the function \(a - e^{\lambda t}\) where \(a\) and \(\lambda\) are parameters that control the initial productivity and the rate of its decay as generations of inbreeding progress. We force \(a\) to be positive using the exp() function, which expresses it on the exponential scale. Large \(a\) indicates higher starting productivity at generation 0 (we started observation at generation 1, the productivity for which is given by \(a - e^{\lambda}\)). Positive values of \(\lambda\) indicate that productivity declines with inbreeding, which is our strong expectation and clearly the case following inspection of the raw data (see Figure SX).

We model inbreeding depression while including zero values for all rows where a lineage was extinct. This helps combat underestimation of the decay parameter, caused by the non-random extinction of lineages, where high fitness lineages become over-represented as the generations of inbreeding progress (i.e. selection).

Fixed and random effects

In the brms non-linear syntax, different formulas can be fit for each parameter. We fit the same fixed effects for \(a\) and \(\lambda\): Evolution treatment and Block. We fit ‘Lineage’ as a random effect to account for repeated measurements taken on each lineage for \(a\), but are unable to do this for \(\lambda\), as individual lineage productivity curves are highly heteroskedastic, and are skewed by extinction events. To minimise pseudoreplication for \(\lambda\), we fit Cross as a random effect (currently only on \(\lambda\)), as we do for the extinction data.

\(~\)

Simulate the curve, with the priors we will specify

n <- 1e4

# define the x-axis breaks
at <- 1:20

# how many prior draws would you like?
n_draws <- 200

# simulate
set.seed(16)

prior <-
  tibble(index = 1:n,
         a   = rnorm(n, mean = 4.5, sd = 0.5),
         lambda     = rnorm(n, mean = 0.2, sd = 0.1)) %>% 
  slice_sample(n = n_draws) %>% 
  expand(nesting(index, a, lambda),
         Generation = seq(from = 0, to = 20, length.out = 1e2)) %>% 
  mutate(productivity = exp(a - lambda * Generation)) 


prior %>% 
  ggplot(aes(x = Generation, y = productivity, group = index)) +
  geom_line(size = 1/2, alpha = 1/4, colour = met.brewer("Hiroshige")[2]) +
  theme_tidybayes() +
  scale_y_continuous(limits = c(0,300), expand = expansion(mult = c(0, .1))) +
  scale_x_continuous(limits = c(0,20), expand = c(0, 0)) +
  labs(y = "Lineage productivity", x = "Generation of inbreeding") +
  theme(text = element_text(size = 14))

Figure XX: Prior predictive simulation for the productivity decline model. The plot shows the results from 100 prior draws.

Fit the non-linear model

nonlinear_productivity <- 
  brm(bf(Collection_window_offspring ~ exp(a - (lambda * Generation)),
         a ~ 0 + Treatment * Block + (1|Lineage), 
         lambda ~ 0 + Treatment * Block + (1|Cross), 
         nl = TRUE),
      data = Productivity_data_clean,
      family = negbinomial(link = "identity"),
      prior = c(prior(normal(4.5, 0.5), class = b, coef = TreatmentControl, nlpar = "a"),
                prior(normal(4.5, 0.5), class = b, coef = TreatmentFemale, nlpar = "a"),
                prior(normal(4.5, 0.5), class = b, coef = TreatmentMale, nlpar = "a"),
                prior(normal(0, 0.5), class = b, coef = Block2, nlpar = "a"),
                prior(normal(0.2, 0.1), class = b, coef = TreatmentControl, nlpar = "lambda"),
                prior(normal(0.2, 0.1), class = b, coef = TreatmentFemale, nlpar = "lambda"),
                prior(normal(0.2, 0.1), class = b, coef = TreatmentMale, nlpar = "lambda"),
                prior(normal(0, 0.1), class = b, coef = Block2, nlpar = "lambda"),
                prior(gamma(3, 1.5), class = sd, nlpar = "a"),
                prior(gamma(0.1, 2), class = sd, nlpar = "lambda")),
      control = list(adapt_delta = 0.8, max_treedepth = 15), seed = 1,
      iter = 30000, warmup = 5000, chains = 4, cores = 4,
      file = "Fits/non_linear_productivity_model_2")

How does our curve fit the data

new_data <- 
  Productivity_data_clean %>% 
  select(Generation, Treatment, Block) %>%
  distinct() %>%
  mutate(key = paste("V", 1:n(), sep = ""))

preds <- as.data.frame(fitted(nonlinear_productivity, newdata = new_data, re_formula = NA, summary=F)) %>% 
  mutate(draw = 1:n()) %>% 
  gather(key, Collection_window_offspring, -draw) %>% 
  as_tibble() %>% 
  left_join(new_data, by = "key") %>% 
  select(-key) %>% 
    mutate(Treatment = case_when(
    Treatment == "Female" ~ "Female-limited",
    Treatment == "Male" ~ "Male-limited",
    Treatment == "Control" ~ "Control"))

preds_summary <-
  preds %>% 
  group_by(Treatment, Generation, Block) %>%
  median_qi(Collection_window_offspring, .width = 0.5)

nl_p1 <-
  Productivity_data_clean %>% 
  filter(Block == 1) %>%  
  ggplot(aes(x = Generation, y = Collection_window_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.2) +
 # geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7], alpha = 0.4) +
  geom_ribbon(data = preds_summary %>% filter(Block == "1"), 
             aes(ymin = .lower, ymax = .upper, fill = Treatment), alpha = 1/2) +
  geom_line(aes(group = Treatment, colour = Treatment), data = preds_summary %>% filter(Block == 1),
            size = 1, alpha = 1, linetype = 5) +
  scale_linetype_manual(values = c(1, 2, 3)) +
  scale_colour_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_y_continuous(expand = expansion(mult = c(0.01, 0))) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20), ylim = c(0, 150)) +
  labs(y = "Lineage productivity", x = "Generation of inbreeding", fill = "Selection response\nhistory") +
  theme(text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11),
        legend.position = c(.99, .99),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6))

nl_p2 <-
  Productivity_data_clean %>% filter(Block == 2) %>% 
  ggplot(aes(x = Generation, y = Collection_window_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.2) +
  # geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7], alpha = 0.4) +
  geom_ribbon(data = preds_summary %>% filter(Block == 2), 
              aes(ymin = .lower, ymax = .upper, fill = Treatment), alpha = 1/2) +
  geom_line(aes(group = Treatment, colour = Treatment), data = preds_summary %>% filter(Block == 2),
            size = 1, alpha = 1, linetype = 5) +
  scale_linetype_manual(values = c(1, 2, 3)) +
  scale_colour_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_y_continuous(expand = expansion(mult = c(0.01, 0))) +
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20), ylim = c(0, 150)) +
  labs(y = "Lineage productivity", x = "Generation of inbreeding", subtitle = "Block 2", fill = "Selection response\nhistory") +
  theme(text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11),
        legend.position = c(.99, .99),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6))

\(~\)

Estimating \(a\) and \(\lambda\)

Initial_productivity_estimates <-
as_draws_df(nonlinear_productivity, variable = "^b_a", regex = TRUE) %>% 
  mutate(`Female-limited B1` = b_a_TreatmentFemale,
         `Male-limited B1` = b_a_TreatmentMale,
         `Control B1` = b_a_TreatmentControl,
         `Female-limited B2` = b_a_TreatmentFemale + b_a_Block2 + `b_a_TreatmentFemale:Block2`,
         `Male-limited B2` = b_a_TreatmentMale + b_a_Block2 + `b_a_TreatmentMale:Block2`,
         `Control B2` = b_a_TreatmentControl + b_a_Block2) %>%
  select(`Female-limited B1`, `Male-limited B1`, `Control B1`,
         `Female-limited B2`, `Male-limited B2`, `Control B2`) %>% 
  mutate_all(~ exp(.x)) %>% 
  mutate(posterior_sample = 1:n()) %>% 
  gather(Evolution_treatment, a, -posterior_sample) %>% 
  separate(col = Evolution_treatment, sep = " ", into = c("Evolution_treatment", "Block"))
  

Initial_productivity_plot_B1 <-
  Initial_productivity_estimates %>% 
  filter(Block == "B1") %>%
  
  ggplot(aes(x = a, y = Evolution_treatment)) +
  stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + 
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  coord_cartesian(xlim = c(50, 150)) +
  labs(x=expression(paste("Initial productivity parameter ",italic("a"))), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))


Initial_productivity_plot_B2 <-
  Initial_productivity_estimates %>% 
  filter(Block == "B2") %>%
  
  ggplot(aes(x = a, y = Evolution_treatment)) +
  stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x=expression(paste("Initial productivity parameter ",italic("a"))), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))


decay_estimates <-  
  as_draws_df(nonlinear_productivity, variable = "^b_lambda", regex = TRUE) %>% 
  mutate(`Female-limited B1` = b_lambda_TreatmentFemale,
         `Male-limited B1` = b_lambda_TreatmentMale,
         `Control B1` = b_lambda_TreatmentControl,
         `Female-limited B2` = b_lambda_TreatmentFemale + b_lambda_Block2 + `b_lambda_TreatmentFemale:Block2`,
         `Male-limited B2` = b_lambda_TreatmentMale + b_lambda_Block2 + `b_lambda_TreatmentMale:Block2`,
         `Control B2` = b_lambda_TreatmentControl + b_lambda_Block2) %>%
 select(`Female-limited B1`, `Male-limited B1`, `Control B1`,
         `Female-limited B2`, `Male-limited B2`, `Control B2`) %>% 
  mutate(posterior_sample = 1:n()) %>% 
  gather(Evolution_treatment, lambda, -posterior_sample) %>%
  separate(col = Evolution_treatment, sep = " ", into = c("Evolution_treatment", "Block"))
  

decay_plot_B1 <-
  decay_estimates %>% 
  filter(Block == "B1") %>% 
  ggplot(aes(x = lambda, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white", 
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x=expression(paste("Decay rate parameter ", lambda,)), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

decay_plot_B2 <-
  decay_estimates %>% 
  filter(Block == "B2") %>% 
  ggplot(aes(x = lambda, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x=expression(paste("Decay rate parameter ", lambda,)), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

Create leaf plots like those in Figure 1

productivity_curve <-
  nonlinear_productivity %>% 
  as_draws_df() %>% 
  select(contains("b_")) %>% 
  mutate(across(1:3, ~ exp(.x)),
         Control_0  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*0),
         Control_1  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*1),
         Control_2  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*2),
         Control_3  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*3),
         Control_4  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*4),
         Control_5  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*5),
         Control_6  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*6),
         Control_7  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*7),
         Control_8  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*8),
         Control_9  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*9),
         Control_10  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*10),
         Control_11  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*11),
         Control_12  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*12),
         Control_13  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*13),
         Control_14  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*14),
         Control_15  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*15),
         Control_16  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*16),
         Control_17  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*17),
         Control_18  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*18),
         Control_19  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*19),
         Control_20  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*20),
         Female_0  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*0),
         Female_1  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*1),
         Female_2  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*2),
         Female_3  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*3),
         Female_4  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*4),
         Female_5  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*5),
         Female_6  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*6),
         Female_7  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*7),
         Female_8  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*8),
         Female_9  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*9),
         Female_10  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*10),
         Female_11  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*11),
         Female_12  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*12),
         Female_13  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*13),
         Female_14  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*14),
         Female_15  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*15),
         Female_16  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*16),
         Female_17  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*17),
         Female_18  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*18),
         Female_19  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*19),
         Female_20  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*20),
         Male_0  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*0),
         Male_1  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*1),
         Male_2  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*2),
         Male_3  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*3),
         Male_4  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*4),
         Male_5  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*5),
         Male_6  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*6),
         Male_7  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*7),
         Male_8  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*8),
         Male_9  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*9),
         Male_10  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*10),
         Male_11  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*11),
         Male_12  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*12),
         Male_13  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*13),
         Male_14  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*14),
         Male_15  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*15),
         Male_16  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*16),
         Male_17  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*17),
         Male_18  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*18),
         Male_19  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*19),
         Male_20  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*20)) %>% 
  select(-c(contains("b_")))

Difference_gens_productivity <- 
  preds %>% 
  group_by(Generation, Treatment, Block) %>% 
  ungroup() %>% 
  pivot_wider(values_from = "Collection_window_offspring", names_from = "Treatment") %>% 
  mutate(diff.mc = `Male-limited` - Control,
         diff.mf = `Male-limited` - `Female-limited`,
         diff.fc = `Female-limited` - Control) %>% 
  select(Generation, Block, contains("diff")) %>% 
  pivot_longer(cols = contains("diff"), values_to = "survival_diff", names_to = "Difference contrast") 

# Make the three plots

Leaf_plot_mc_productivity_B1 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mc" & Block == "1") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProductivity diff.",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_mc_productivity_B2 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mc" & Block == "2") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProductivity diff.",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_mf_productivity_B1 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mf" & Block == "1") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_mf_productivity_B2 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mf" & Block == "2") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_fc_productivity_B1 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.fc" & Block == "1") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_fc_productivity_B2 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.fc" & Block == "2") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Figure 2 and Figure SX

(nl_p1 / (Initial_productivity_plot_B1 + decay_plot_B1)) / (Leaf_plot_mc_productivity_B1 + Leaf_plot_mf_productivity_B1 + Leaf_plot_fc_productivity_B1) +
  plot_annotation(tag_levels = 'a')

Figure 2. the figure to end all figures again. Block 1

\(~\)

(nl_p2 / (Initial_productivity_plot_B2 + decay_plot_B2)) / (Leaf_plot_mc_productivity_B2 + Leaf_plot_mf_productivity_B2 + Leaf_plot_fc_productivity_B2) +
  plot_annotation(tag_levels = 'a')

Figure SX. the figure to end all figures again. Block 2

LS0tCnRpdGxlOiAiU2VsZWN0aW9uIGFtb25nIG1hbGVzIHJlZHVjZXMgbXV0YXRpb24gbG9hZCIKYXV0aG9yOiAiVGhvbWFzIEtlYW5leSwgSGVpZGkgV29uZywgWGlhbWVuZyBRaSwgVGhlcmVzYSBKb25lcyBhbmQgTHVrZSBIb2xtYW4iCiNiaWJsaW9ncmFwaHk6ICJzdXBwX3JlZmVyZW5jZXMuYmliIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgZGVwdGg6IDEKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRoZW1lOiB5ZXRpCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBGQUxTRSkKYGBgCgojIExvYWQgcGFja2FnZXMKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyB0aWR5IHN0eWxlIGNvZGluZwpsaWJyYXJ5KGJybXMpICMgQmF5ZXNpYW4gbW9kZWxzCmxpYnJhcnkoYmF5ZXNwbG90KSAjIHByZXR0eSBiYXllcyB2aXN1YWxzCmxpYnJhcnkodGlkeWJheWVzKSAjIEJheWVzaWFuIGFlc3RoZXRpY3MKbGlicmFyeShsb28pICMgdG8gdXNlIGluZm9ybWF0aW9uIGNyaXRlcmlhIGluIGJybXMgbW9kZWxzCmxpYnJhcnkoTWV0QnJld2VyKSAjIGNvbG91cnMKbGlicmFyeShyY2FydG9jb2xvcikgIyBtb3JlIGNvbG91cnMKbGlicmFyeShwYW5kZXIpICMgdGFibGVzCmxpYnJhcnkoa2FibGVFeHRyYSkgIyB0YWJsZXMKbGlicmFyeShwYXRjaHdvcmspICMgcHV0dGluZyBwbG90cyB0b2dldGhlcgpsaWJyYXJ5KERUKSAjIGZvciBzZWFyY2gtIGFuZCBzYXZlYWJsZSB0YWJsZXMKbGlicmFyeShnZ2Rpc3QpICMgZm9yIHJpYmJvbiBwbG90CmBgYAoKIyBTdXBwbGVtZW50YXJ5IG1ldGhvZHMKCiR+JAoKKipUYWJsZSBTMSoqLiBSZWNpcGUgZm9yIGZvb2QgbWVkaXVtIHVzZWQgaW4gb3VyIGV4cGVyaW1lbnQuIFRoZSBwcm92aWRlZCBxdWFudGl0aWVzIG1ha2UgfiAxIGxpdHJlIG9mIGZvb2QuCgpgYGB7cn0KdGliYmxlKCJJbmdyZWRpZW50cyIgPSBjKCJTb3kgZmxvdXIiLCAiQ29ybm1lYWwiLCAiWWVhc3QiLCAiRGV4dHJvc2UiLCAiQWdhciIsICJXYXRlciIsICJUZWdvc2VwdCIsICJBY2lkIG1peCAoNCBtTCBvcnRob3Bob3NwaG9yaWMgYWNpZCwgNDEgbUwgcHJvcGlvbmljIGFjaWQsIDU1IG1MIHdhdGVyIHRvIG1ha2UgMTAwIG1MKSIpLAogICAgICAgIlF1YW50aXR5IiA9IGMoIjIwIGciLCAiNzMgZyIsICIzNSBnIiwgIjc1IGciLCAiNiBnIiwgIjEwMDAgbUwiLCAiMTcgbUwiLCAiMTQgbUwiKSkgJT4lIAogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mKQpgYGAKCiR+JAoKIyBBbmFseXNpcwoKJH4kCgojIyBNb3J0YWxpdHkgYW5hbHlzaXMKCiR+JAoKV2UgY29uZHVjdGVkIHNpbmdsZS1wYWlyIGZ1bGwtc2libGluZyBjcm9zc2VzIHRvIGVyb2RlIGhldGVyb3p5Z29zaXR5IGFjcm9zcyB0aGUgZ2Vub21lLCB0aGVyZWJ5IGV4cG9zaW5nIG11dGF0aW9uIGxvYWQuIE91ciBwcm94aWVzIGZvciBtdXRhdGlvbiBsb2FkIC0gZXh0aW5jdGlvbiByYXRlIGFuZCBwcm9kdWN0aXZpdHkgZGVjbGluZSAtIG1heSBhbHNvIGhhdmUgYmVlbiBhZmZlY3RlZCBieSBkaWZmZXJlbmNlcyBpbiB0aGUgaW50ZW5zaXR5IG9mIGludGVybG9jdXMgc2V4dWFsIGNvbmZsaWN0IGJldHdlZW4gbGluZWFnZXMgY2FycnlpbmcgYXV0b3NvbWVzIHdpdGggZGlmZmVyZW50IHNlbGVjdGlvbiByZXNwb25zZSBoaXN0b3JpZXMuICoqV2Ugc3BlY2lmaWNhbGx5IGRlc2lnbmVkIG91ciBleHBlcmltZW50IHRvIG1pbmltaXNlIHRoaXMgZWZmZWN0KiosIGJ5IGVuZm9yY2luZyBtb25vZ2FteSBiZXR3ZWVuIGFsbCBicmVlZGluZyBpbmRpdmlkdWFscyBhY3Jvc3MgdGhlIGV4dGluY3Rpb24gYXNzYXkuIEhvd2V2ZXIsIHdlIGNhbm5vdCBkaXNjb3VudCBtYWxlcyBjYXJyeWluZyBtYWxlLWxpbWl0ZWQgYXV0b3NvbWVzIGFuZC8gb3IgY29udHJvbCBhdXRvc29tZXMgYmVpbmcgbW9yZSBoYXJtZnVsIHRvIGZlbWFsZXMgdGhhbiBtYWxlcyBjYXJyeWluZyBhdXRvc29tZXMgd2l0aCBhIGZlbWFsZS1saW1pdGVkIHNlbGVjdGlvbiByZXNwb25zZSBoaXN0b3J5LiBUaGlzIG1pZ2h0IG9jY3VyIGJlY2F1c2UgbWFsZSBoYXJtIGlzIGEgYnktcHJvZHVjdCBvZiBtYWxlLW1hbGUgY29tcGV0aXRpb24sIHdoaWNoIGNhbm5vdCByZXNwb25kIHRvIHNlbGVjdGlvbiBpbiB0aGUgZmVtYWxlLWxpbWl0ZWQgdHJlYXRtZW50cy4gRnVydGhlcm1vcmUsIHRyYWl0cyBnZW5ldGljYWxseSBjb3JyZWxhdGVkIHdpdGggaGFybSBzdWNoIGFzIGFjdGl2aXR5IGxldmVscyBvciBtZXRhYm9saWMgcmF0ZSBtYXkgYmUgc2VsZWN0ZWQgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbiBhbW9uZyBmZW1hbGVzLCBhcyB0aGVzZSB0cmFpdHMgYXJlIGhpZ2hseSBzZXh1YWxseSBkaW1vcnBoaWMuIFRoaXMgbWF5IGRyaXZlIHRoZSBldm9sdXRpb24gb2YgcmVkdWNlZCBoYXJtIGR1cmluZyBmZW1hbGUtbGltaXRlZCBldm9sdXRpb24uIAoKV2Ugb2JzZXJ2ZSAxMzUgZmVtYWxlICg2LjIlKSBhbmQgMjEgKDElKSBtYWxlIG1vcnRhbGl0aWVzIGFjcm9zcyB0aGUgMjE4NCBfRHJvc29waGlsYV8gdmlhbHMgdXNlZCBkdXJpbmcgdGhlIDIwIGdlbmVyYXRpb25zIG9mIHRoZSBleHBlcmltZW50ICh3ZSBkbyBub3QgaW5jbHVkZSB0aGUgOSBmaW5hbCBnZW5lcmF0aW9ucyBvYnNlcnZlZCBpbiBCbG9jayAxIGluIHRoaXMgYW5hbHlzaXMpLiBNYWxlIG1vcnRhbGl0eSBkaWQgbm90IG9jY3VyIG9mdGVuIGVub3VnaCB0byBwcm92aWRlIHRoZSBwb3dlciByZXF1aXJlZCBmb3IgZm9ybWFsIGFuYWx5c2lzLiBXZSBpbnN0ZWFkIGZvY3VzIG9uIG1vZGVsbGluZyBmZW1hbGUgbW9ydGFsaXR5IGFuZCB0ZXN0IHdoZXRoZXIgdGhpcyBpcyBhZmZlY3RlZCBieSBzZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yeS4gCgpXZSB0ZXN0IHRoaXMgaHlwb3RoZXNpcyB0byBhc3Nlc3Mgd2hldGhlciBpdCBpcyByZXF1aXJlZCB0byBjZW5zb3IgbGluZWFnZXMgd2hlcmUgdGhlIGJyZWVkaW5nIGZlbWFsZSBkaWVkIGluIHRoZSBnZW5lcmF0aW9uIG9mIGV4dGluY3Rpb24uCgokfiQKCiMjIyBMb2FkIGluIHRoZSBkYXRhCgpgYGB7cn0KCm1vcnRhbGl0eV9kYXRhIDwtIAogIHJlYWRfY3N2KCJEYXRhL01vcnRhbGl0eV9kYXRhLmNzdiIpICU+JSAKICByb3dpZF90b19jb2x1bW4oIkxpbmVhZ2UiKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSA4OjI3LCBuYW1lc190byA9ICJHZW5lcmF0aW9uIiwgdmFsdWVzX3RvID0gIkZlbWFsZV9tb3J0YWxpdHkiKSAlPiUgCiAgbXV0YXRlKGFjcm9zcygxOjcsIGFzLmZhY3RvciksCiAgICAgICAgIEdlbmVyYXRpb24gPSBhcy5pbnRlZ2VyKHN0cl9yZW1vdmUoR2VuZXJhdGlvbiwgIkdlbl8iKSksCiAgICAgICAgIE1hbGVfbW9ydGFsaXR5ID0gRmVtYWxlX21vcnRhbGl0eSwKICAgICAgICAgRmVtYWxlX21vcnRhbGl0eSA9IGlmX2Vsc2UoRmVtYWxlX21vcnRhbGl0eSA9PSAiRkVNQUxFIiB8IEZlbWFsZV9tb3J0YWxpdHkgPT0gIkJPVEgiLCAxLCAwKSwKICAgICAgICAgTWFsZV9tb3J0YWxpdHkgPSBpZl9lbHNlKE1hbGVfbW9ydGFsaXR5ID09ICJNQUxFIiB8IE1hbGVfbW9ydGFsaXR5ID09ICJCT1RIIiwgMSwgMCkpICU+JSAKICByZW5hbWUoRXZvbHV0aW9uX3RyZWF0bWVudCA9IFRyZWF0bWVudCkKCiMgQ3JlYXRlIGEgZnVuY3Rpb24gdG8gYnVpbGQgSFRNTCBzZWFyY2hhYmxlIHRhYmxlcwoKbXlfZGF0YV90YWJsZSA8LSBmdW5jdGlvbihkZil7CiAgZGF0YXRhYmxlKAogICAgZGYsIHJvd25hbWVzPUZBTFNFLAogICAgYXV0b0hpZGVOYXZpZ2F0aW9uID0gVFJVRSwKICAgIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICAiQnV0dG9ucyIpLAogICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICBkZWZlclJlbmRlcj1UUlVFLAogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLAogICAgICBzY3JvbGxDb2xsYXBzZT1UUlVFLAogICAgICBidXR0b25zID0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KAogICAgICAgICAgZXh0ZW5kID0gJ3BkZicsCiAgICAgICAgICBwYWdlU2l6ZSA9ICdBNCcsCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLAogICAgICAgICAgZmlsZW5hbWUgPSAnbW9ydGFsaXR5X2RhdGEnKSksCiAgICAgIHBhZ2VMZW5ndGggPSA4NTAwCiAgICApCiAgKQp9CgpteV9kYXRhX3RhYmxlKG1vcnRhbGl0eV9kYXRhICU+JSAKICAgICAgICAgICAgICAgIHNlbGVjdChNb3RoZXJfc3RyYWluLCBGYXRoZXJfc3RyYWluLCBDcm9zcywgTGluZWFnZSwgQmxvY2ssIEdlbmVyYXRpb24sIEV2b2x1dGlvbl90cmVhdG1lbnQsIEZlbWFsZV9tb3J0YWxpdHksIE1hbGVfbW9ydGFsaXR5KSkKCmBgYAoKJH4kCgoqKkNvbHVtbiBleHBsYW5hdGlvbnMqKgoKYE1vdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgYEV2b2x1dGlvbl90cmVhdG1lbnRgLiBUaGlzIGNvbHVtbiBzaG93cyB0aGUgc3RyYWluIHRoYXQgdGhlIGZvdW5kaW5nIGZlbWFsZSBvZiB0aGUgbGluZWFnZSB3YXMgZGVyaXZlZCBmcm9tLgoKYEZhdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgZXZvbHV0aW9uIHRyZWF0bWVudC4gVGhpcyBjb2x1bW4gc2hvd3MgdGhlIHN0cmFpbiB0aGF0IHRoZSBmb3VuZGluZyBtYWxlIG9mIHRoZSBsaW5lYWdlIHdhcyBkZXJpdmVkIGZyb20uCgpgQ3Jvc3NgOiBhbiBpZGVudGlmeWluZyBJRCBmb3IgZWFjaCBvZiB0aGUgMzYgY29tYmluYXRpb25zIG9mIGBNb3RoZXIgc3RyYWluYCBhbmQgYEZhdGhlciBzdHJhaW5gLiAKCmBMaW5lYWdlYDogbGluZXMgb2YgZmxpZXMgZm91bmRlZCBieSBzaW5nbGUgaW5zZW1pbmF0ZWQgZmVtYWxlcyBpbiBnZW5lcmF0aW9uIHplcm8uIFdlIGdlbmVyYXRlZCB0aGUgbmV4dCBnZW5lcmF0aW9uIG9mIGVhY2ggbGluZWFnZSBieSBjcm9zc2luZyBhIHNpbmdsZSBmdWxsLXNpYmxpbmcgZHlhZC4KCmBCbG9ja2A6IHRoZSBleHBlcmltZW50IHdhcyBydW4gaW4gMiBkaXN0aW5jdCBibG9ja3MsIHVzaW5nIGZsaWVzIHNlcGFyYXRlZCBieSA5IGdlbmVyYXRpb25zLgoKYEdlbmVyYXRpb25gOiB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgZXh0aW5jdGlvbiBhc3NheSwgcmFuZ2luZyBmcm9tIDEgdG8gMjAuIAoKYEV2b2x1dGlvbl90cmVhdG1lbnRgOiB0aGUgc3RyYWlucyBoYWQgYmVlbiBleHBvc2VkIHRvIG9uZSBvZiB0aHJlZSBldm9sdXRpb25hcnkgY29uZGl0aW9ucyBmb3IgMjAgZ2VuZXJhdGlvbnM6IGEgZmVtYWxlLWxpbWl0ZWQgcmVzcG9uc2UgdG8gc2VsZWN0aW9uLCBhIG1hbGUtbGltaXRlZCByZXNwb25zZSBhbmQgYSBjb250cm9sIGNvbmRpdGlvbiB3aGVyZSBhbiBldm9sdXRpb25hcnkgcmVzcG9uc2Ugb2NjdXJyZWQgaW4gYm90aCBzZXhlcy4KCmBGZW1hbGVfbW9ydGFsaXR5YDogYSAwIGluZGljYXRlcyB0aGUgZmVtYWxlIHN1cnZpdmVkIHVudGlsIHNoZSB3YXMgcmVtb3ZlZCBmcm9tIHRoZSAzLWRheSBicmVlZGluZyB2aWFsLiBBIDEgaW5kaWNhdGVzIHNoZSBkaWVkIGR1cmluZyB0aGlzIHBlcmlvZC4gRmVtYWxlcyB3ZXJlIDEtNCBkYXlzIG9sZCB3aGVuIHRoZXkgZW50ZXJlZCB0aGUgYnJlZWRpbmcgdmlhbC4KCmBNYWxlX21vcnRhbGl0eWA6IHNlZSBgRmVtYWxlX21vcnRhbGl0eWAsIGV4Y2VwdCB0aGlzIGNvbHVtbiBkb2N1bWVudHMgbWFsZSBtb3J0YWxpdHkgaW4gdGhlIGJyZWVkaW5nIHZpYWxzLgoKJH4kCgojIyMgTW9kZWxsaW5nIGFwcHJvYWNoCgokfiQKCldlIGZpdCBhIGJpbm9taWFsIG1vZGVsIHdpdGggYEV2b2x1dGlvbl90cmVhdG1lbnRgIGFuZCBgQmxvY2tgIGFzIGZpeGVkIGVmZmVjdHMgYXMgd2VsbCBhcyBgTGluZWFnZWAgYW5kIGBDcm9zc2AgYXMgcmFuZG9tIGVmZmVjdHMuCgpgYGB7cn0KbW9ydGFsaXR5X21vZGVsIDwtIAogIGJybShGZW1hbGVfbW9ydGFsaXR5IH4gMSArIEV2b2x1dGlvbl90cmVhdG1lbnQgKyBCbG9jayArICgxfENyb3NzKSArICgxfExpbmVhZ2UpLAogICAgICBkYXRhID0gbW9ydGFsaXR5X2RhdGEgJT4lIGZpbHRlcihGZW1hbGVfbW9ydGFsaXR5ICE9ICJOQSIpLAogICAgICBmYW1pbHkgPSBiZXJub3VsbGksCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMiksIGNsYXNzID0gSW50ZXJjZXB0KSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSBiKSwKICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSksCiAgICAgIGl0ZXIgPSA0MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsIHNlZWQgPSAxLAogICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTUpLAogICAgICBmaWxlID0gIkZpdHMvbW9ydGFsaXR5X21vZGVsIikKYGBgCgoKIyMjIEV4dHJhY3QgbW9kZWwgcHJlZGljdGlvbnMgYW5kIHBsb3QKCmBgYHtyfQoKIyB0aGVzZSBhcmUgc3BlY2lmaWMgdG8gYmxvY2sgMSwgYnV0IHRoaXMgZG9lc24ndCByZWFsbHkgbWF0dGVyIGJlY2F1c2UgdGhlcmUgaXMgbm8gaW50ZXJhY3Rpb24gYmV0d2VlbiB0cmVhdG1lbnQgYW5kIGJsb2NrLgoKbW9ydGFsaXR5X3ByZWRpY3Rpb25zIDwtCiAgbW9ydGFsaXR5X21vZGVsICU+JSAKICBhc19kcmF3c19kZigpICU+JSAKICBtdXRhdGUoQ29udHJvbCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQpLAogICAgICAgICBgRmVtYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudEZlbWFsZSksCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUpKSAlPiUgCiAgc2VsZWN0KENvbnRyb2wsIGBGZW1hbGUtbGltaXRlZGAsIGBNYWxlLWxpbWl0ZWRgKQogICAgCiMgcHV0IGluIGVhc3kgdG8gcGxvdCBmb3JtYXQKCm1vcnRhbGl0eV9wcmVkaWN0aW9uc19sb25nIDwtCiAgbW9ydGFsaXR5X3ByZWRpY3Rpb25zICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGV2ZXJ5dGhpbmcoKSwgbmFtZXNfdG8gPSAiRXZvbHV0aW9uX3RyZWF0bWVudCIsIHZhbHVlc190byA9ICJNb3J0YWxpdHkiKQoKIyBjYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gZWFjaCB0cmVhdG1lbnQKCm1vcnRhbGl0eV9kaWZmIDwtCiAgbW9ydGFsaXR5X3ByZWRpY3Rpb25zICU+JSAKICBtdXRhdGUoYENvbnRyb2wgLSBNYWxlLWxpbWl0ZWRgID0gQ29udHJvbCAtIGBNYWxlLWxpbWl0ZWRgLAogICAgICAgICBgTWFsZS1saW1pdGVkIC0gRmVtYWxlLWxpbWl0ZWRgID0gYE1hbGUtbGltaXRlZGAgLSBgRmVtYWxlLWxpbWl0ZWRgLAogICAgICAgICBgQ29udHJvbCAtIEZlbWFsZS1saW1pdGVkYCA9IENvbnRyb2wgLSBgRmVtYWxlLWxpbWl0ZWRgKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSA0OjYsIG5hbWVzX3RvID0gIkRpZmZlcmVuY2VfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAiRGlmZmVyZW5jZSIpICU+JSAKICBzZWxlY3QoY29udGFpbnMoIkRpZmYiKSkKCmBgYAoKIyMjIEJ1aWxkIEZpZ3VyZSBTMQoKYGBge3J9Cm1vcnRhbGl0eV9wbG90IDwtCiAgbW9ydGFsaXR5X3ByZWRpY3Rpb25zX2xvbmcgJT4lIAogIGdncGxvdChhZXMoeCA9IE1vcnRhbGl0eSwgeSA9IEV2b2x1dGlvbl90cmVhdG1lbnQpKSArCiAgICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBFdm9sdXRpb25fdHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsIAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBzbGFiX2NvbG91ciA9ICJibGFjayIsIHNsYWJfc2l6ZSA9IDAuOCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDUpKSArCiAgbGFicyh4PSAiRmVtYWxlIG1vcnRhbGl0eSAocHJvcC4pIiwgeSA9ICJTZWxlY3Rpb24gcmVzcG9uc2Vcbmhpc3RvcnkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKbW9ydGFsaXR5X2RpZmZfcGxvdCA8LSAKICBtb3J0YWxpdHlfZGlmZiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gRGlmZmVyZW5jZSwgeSA9IGZjdF9yZWxldmVsKERpZmZlcmVuY2VfY29udHJhc3QsICJGZW1hbGUgLSBDb250cm9sIiwgIk1hbGUgLSBGZW1hbGUiLCAiTWFsZSAtIENvbnRyb2wiKSkpICsKICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBEaWZmZXJlbmNlX2NvbnRyYXN0KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUsCiAgICAgICAgICAgICAgIHNsYWJfY29sb3VyID0gImJsYWNrIiwgc2xhYl9zaXplID0gMC44KSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoY2FydG9fcGFsKDcsICJQZWFjaCIpWzJdLCBjYXJ0b19wYWwoNywgIlB1cnAiKVsxXSwgY2FydG9fcGFsKDcsICJUZWFsR3JuIilbMV0pKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJEaWZmLiBpbiBtb3J0YWxpdHkiLCB5ID0gIlRyZWF0bWVudCBjb250cmFzdCIpICsKICAjc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoLTQsIDYsIDIpKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcsIGNvbG9yPU5BKSwgI3RyYW5zcGFyZW50IHBsb3QgYmcKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKbW9ydGFsaXR5X3Bsb3QgLyBtb3J0YWxpdHlfZGlmZl9wbG90ICsKICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICdhJykKYGBgCgoqKkZpZ3VyZSBTMSoqLiBGZW1hbGUgbW9ydGFsaXR5IGlzIGxlc3MgZnJlcXVlbnQgaW4gbGluZWFnZXMgd2l0aCBmZW1hbGUtbGltaXRlZCBzZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yaWVzLCBzdWdnZXN0aW5nIHRoYXQgbWFsZSBoYXJtIG1heSBiZSBsZXNzIGludGVuc2UgaW4gdGhlc2UgbGluZWFnZXMuIFBhbmVsICoqYSoqIHNob3dzIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHRoZSBudW1iZXIgb2YgbW9ydGFsaXR5IGV2ZW50cyBhcyBhIHByb3BvcnRpb24gb2YgdGhlIHRvdGFsIG51bWJlciBvZiB2aWFscyB0aGF0IGhvdXNlZCBsaW5lYWdlcyB0aHJvdWdob3V0IHRoZSBmaXJzdCAyMCBnZW5lcmF0aW9ucyBvZiB0aGUgZXh0aW5jdGlvbiBhc3NheSwgc3BsaXQgYnkgc2VsZWN0aW9uIHJlc3BvbnNlIGhpc3RvcnkuIFBhbmVsICoqYioqIHNob3dzIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gZWFjaCB0cmVhdG1lbnQuIFRoZSBwb2ludHMgc2hvdyB0aGUgZXN0aW1hdGVkIG1lYW4sIHdpdGggYXNzb2NpYXRlZCA2NiBhbmQgOTUlIGNyZWRpYmxlIGludGVydmFscy4gCgokfiQKClRvIGF2b2lkIHRoaXMgY29uZm91bmRpbmcgb3VyIG1lYXN1cmUgb2YgbXV0YXRpb24gbG9hZCwgd2UgY2FuIGNlbnNvciBleHRpbmN0aW9uIGV2ZW50cyB0aGF0IGNvLW9jY3VyIHdpdGggZmVtYWxlIG1vcnRhbGl0eS4KCiR+JAoKIyMgRXh0aW5jdGlvbiBhbmFseXNpcwoKIyMjIExvYWQgaW4gdGhlIGV4dGluY3Rpb24gZGF0YSAKCiR+JAoKYGBge3J9CgpleHRpbmN0aW9uX2RhdGEgPC0gCiAgcmVhZF9jc3YoIkRhdGEvRXh0aW5jdGlvbl9kYXRhLmNzdiIpIAoKIyBCbG9jayAxIHJ1bnMgZm9yIDI5IGdlbmVyYXRpb25zLCB3aGlsZSBCbG9jayAyIG9ubHkgcnVucyBmb3IgMjAuIFRvIGNhbGN1bGF0ZSB0aGUgY2Vuc29yaW5nIHZhcmlhYmxlLCB3ZSBuZWVkIHRvIHNwbGl0IHRoZXNlIGJ5IEJsb2NrLCBtdXRhdGUgdGhlIGRhdGEsIHRoZW4gcmViaW5kIHRoZW0gCgpCbG9ja18xIDwtCiAgZXh0aW5jdGlvbl9kYXRhICU+JSAKICBmaWx0ZXIoQmxvY2sgPT0gIjEiKSAlPiUgCiAgIyBoZXJlIHdlIGNyZWF0ZSBhIGNlbnNvcmluZyBjb2x1bW4uIElmIHRoZSBmYW1pbHkgYSkgZXNjYXBlZCBvciB3YXMga2lsbGVkIGJ5IHNvbWV0aGluZyB1bnJlbGF0ZWQgdG8gdGhlIGV4cGVyaW1lbnQgb3IgYikgc3Vydml2ZWQgdGhlIDIwIGdlbmVyYXRpb25zIG9mIHRoZSBleHBlcmltZW50LCB0aGVuIHdlIGNvZGUgYSB2YWx1ZSBvZiAxLiBJZiB0aGUgZmFtaWx5IHdlbnQgZXh0aW5jdCwgd2UgY29kZSBhIHZhbHVlIG9mIDAuIFRoaXMgYWxsb3dzIHVzIHRvIHJpZ2h0IGNlbnNvciB0aGUgZGF0YSwgdGhlcmVieSBwcmVzZXJ2aW5nIHRoZSBpbmZvcm1hdGlvbiBpdCBwcm92aWRlcyBvbiBleHRpbmN0aW9uLgogIG11dGF0ZShhY3Jvc3MoR2VuXzE6R2VuXzI5LCB+cmVwbGFjZV9uYSgueCwgIkVzY2FwZSIpKSwKICAgICAgICAgQ2Vuc29yZWRfYWxpdmUgPSBpZl9lbHNlKEdlbl8yOSA9PSAiWUVTIiwgMSwgMCksCiAgICAgICAgIENlbnNvcmVkX2VzY2FwZSA9IGlmX2Vsc2UoR2VuXzI5ID09ICJFc2NhcGUiLCAxLCAwKSwKICAgICAgICAgQ2Vuc29yZWQgPSBDZW5zb3JlZF9hbGl2ZSArIENlbnNvcmVkX2VzY2FwZSwKICAgICAgICAgYWNyb3NzKEdlbl8xOkdlbl8yOSwgfmlmX2Vsc2UoLnggPT0gIllFUyIsIDEsIDApKSkKICAgICAgICAKCkJsb2NrXzIgPC0KICBleHRpbmN0aW9uX2RhdGEgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiMiIpICU+JSAKICAjIGhlcmUgd2UgY3JlYXRlIGEgY2Vuc29yaW5nIGNvbHVtbi4gSWYgdGhlIGZhbWlseSBhKSBlc2NhcGVkIG9yIHdhcyBraWxsZWQgYnkgc29tZXRoaW5nIHVucmVsYXRlZCB0byB0aGUgZXhwZXJpbWVudCBvciBiKSBzdXJ2aXZlZCB0aGUgMjAgZ2VuZXJhdGlvbnMgb2YgdGhlIGV4cGVyaW1lbnQsIHRoZW4gd2UgY29kZSBhIHZhbHVlIG9mIDEuIElmIHRoZSBmYW1pbHkgd2VudCBleHRpbmN0LCB3ZSBjb2RlIGEgdmFsdWUgb2YgMC4gVGhpcyBhbGxvd3MgdXMgdG8gcmlnaHQgY2Vuc29yIHRoZSBkYXRhLCB0aGVyZWJ5IHByZXNlcnZpbmcgdGhlIGluZm9ybWF0aW9uIGl0IHByb3ZpZGVzIG9uIGV4dGluY3Rpb24uCiAgbXV0YXRlKGFjcm9zcyhHZW5fMTpHZW5fMjAsIH5yZXBsYWNlX25hKC54LCAiRXNjYXBlIikpLAogICAgICAgICBhY3Jvc3MoR2VuXzIxOkdlbl8yOSwgfnJlcGxhY2VfbmEoLngsICJOb3QgbWVhc3VyZWQiKSksCiAgICAgICAgIENlbnNvcmVkX2FsaXZlID0gaWZfZWxzZShHZW5fMjAgPT0gIllFUyIsIDEsIDApLAogICAgICAgICBDZW5zb3JlZF9lc2NhcGUgPSBpZl9lbHNlKEdlbl8yMCA9PSAiRXNjYXBlIiwgMSwgMCksCiAgICAgICAgIENlbnNvcmVkID0gQ2Vuc29yZWRfYWxpdmUgKyBDZW5zb3JlZF9lc2NhcGUsCiAgICAgICAgIGFjcm9zcyhHZW5fMTpHZW5fMjksIH5pZl9lbHNlKC54ID09ICJZRVMiLCAxLCAwKSkpCgojIGNvbWJpbmUgdGhlIEJsb2NrZWQgZGF0YSBiYWNrIGludG8gYSBzaW5nbGUgdGliYmxlCgpleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQgPC0KICByYmluZChCbG9ja18xLCBCbG9ja18yKSAlPiUKICBtdXRhdGUoYWNyb3NzKDE6NywgYXMuZmFjdG9yKSwgCiAgICAgICAgIEdlbnNfdG9fZXh0aW5jdCA9IEdlbl8xICsgR2VuXzIgKyBHZW5fMyArIEdlbl80ICsgCiAgICAgICAgICAgR2VuXzUgKyBHZW5fNiArIEdlbl83ICsgR2VuXzggKyBHZW5fOSArIEdlbl8xMCArIAogICAgICAgICAgIEdlbl8xMSArIEdlbl8xMiArIEdlbl8xMyArIEdlbl8xNCArIEdlbl8xNSArIEdlbl8xNiArIAogICAgICAgICAgIEdlbl8xNyArIEdlbl8xOCArIEdlbl8xOSArIEdlbl8yMCArIEdlbl8yMSArIEdlbl8yMiArIAogICAgICAgICAgIEdlbl8yMyArIEdlbl8yNCArIEdlbl8yNSArIEdlbl8yNiArIEdlbl8yNyArIEdlbl8yOCArIEdlbl8yOSArIDEpICU+JSAKICByZW5hbWUoRXZvbHV0aW9uX3RyZWF0bWVudCA9IFRyZWF0bWVudCwgTGluZWFnZSAgPSBJRCkgJT4lIAogIHNlbGVjdChNb3RoZXJfc3RyYWluLCBGYXRoZXJfc3RyYWluLCBDcm9zcywgTGluZWFnZSwgQmxvY2ssIAogICAgICAgICBFdm9sdXRpb25fdHJlYXRtZW50LCBHZW5zX3RvX2V4dGluY3QsIEdlbl8xOkdlbl8yOSwgQ2Vuc29yZWRfYWxpdmUsIAogICAgICAgICBDZW5zb3JlZF9lc2NhcGUsIENlbnNvcmVkKQoKIyBGaW5kIHRoZSBleHRpbmN0aW9ucyB0aGF0IGNvLW9jY3VyIHdpdGggZmVtYWxlIG1vcnRhbGl0eQoKZXh0aW5jdGlvbl9tb3J0YWxpdHkgPC0KICBsZWZ0X2pvaW4oCiAgICBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQgJT4lIAogICAgICBwaXZvdF9sb25nZXIoY29scyA9IDg6MzYsIG5hbWVzX3RvID0gIkdlbmVyYXRpb24iLCB2YWx1ZXNfdG8gPSAiRXh0YW50IikgJT4lIAogICAgICBtdXRhdGUoR2VuZXJhdGlvbiA9IGFzLmludGVnZXIoc3RyX3JlbW92ZShHZW5lcmF0aW9uLCAiR2VuXyIpKSksCiAgICAKICAgIG1vcnRhbGl0eV9kYXRhCiAgKSAlPiUgCiAgZmlsdGVyKEV4dGFudCA9PSAwICYgRmVtYWxlX21vcnRhbGl0eSA9PSAxKSAlPiUgCiAgbXV0YXRlKENlbnNvcmVkX21vcnRhbGl0eSA9IDEpICU+JSAKICBzZWxlY3QoTGluZWFnZSwgQ2Vuc29yZWRfbW9ydGFsaXR5KQoKZXh0aW5jdGlvbl9kYXRhX3dyYW5nbGVkIDwtIGxlZnRfam9pbihleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQsIGV4dGluY3Rpb25fbW9ydGFsaXR5KSAlPiUgCiAgbXV0YXRlKENlbnNvcmVkX21vcnRhbGl0eSA9IGlmX2Vsc2UoaXMubmEoQ2Vuc29yZWRfbW9ydGFsaXR5KSwgMCwgMSksCiAgICAgICAgIENlbnNvcmVkID0gQ2Vuc29yZWQgKyBDZW5zb3JlZF9tb3J0YWxpdHkpCgojIENyZWF0ZSBhIGZ1bmN0aW9uIHRvIGJ1aWxkIEhUTUwgc2VhcmNoYWJsZSB0YWJsZXMKCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpewogIGRhdGF0YWJsZSgKICAgIGRmLCByb3duYW1lcz1GQUxTRSwKICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsCiAgICBleHRlbnNpb25zID0gYygiU2Nyb2xsZXIiLCAgIkJ1dHRvbnMiKSwKICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICBkb20gPSAnQmZydGlwJywKICAgICAgZGVmZXJSZW5kZXI9VFJVRSwKICAgICAgc2Nyb2xsWD1UUlVFLCBzY3JvbGxZPTQwMCwKICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwKICAgICAgYnV0dG9ucyA9CiAgICAgICAgbGlzdCgncGFnZUxlbmd0aCcsICdjb2x2aXMnLCAnY3N2JywgbGlzdCgKICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLAogICAgICAgICAgcGFnZVNpemUgPSAnQTQnLAogICAgICAgICAgb3JpZW50YXRpb24gPSAnbGFuZHNjYXBlJywKICAgICAgICAgIGZpbGVuYW1lID0gJ2V4dGluY3Rpb25fZGF0YScpKSwKICAgICAgcGFnZUxlbmd0aCA9IDUwMAogICAgKQogICkKfQoKbXlfZGF0YV90YWJsZShleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQpCmBgYAoKKipDb2x1bW4gZXhwbGFuYXRpb25zKioKCmBNb3RoZXIgc3RyYWluYDogd2UgbWVhc3VyZWQgZXh0aW5jdGlvbiBhbmQgcHJvZHVjdGl2aXR5IG9mIGZhbWlsaWVzIGRlcml2ZWQgZnJvbSAzNiBkaWZmZXJlbnQgY3Jvc3Nlcy4gQ3Jvc3NlcyB3ZXJlIG9ubHkgY29uZHVjdGVkIGJldHdlZW4gc3RyYWlucyB0aGF0IGV4cGVyaWVuY2VkIHRoZSBzYW1lIGBFdm9sdXRpb25fdHJlYXRtZW50YC4gVGhpcyBjb2x1bW4gc2hvd3MgdGhlIHN0cmFpbiB0aGF0IHRoZSBmb3VuZGluZyBmZW1hbGUgb2YgdGhlIGxpbmVhZ2Ugd2FzIGRlcml2ZWQgZnJvbS4KCmBGYXRoZXIgc3RyYWluYDogd2UgbWVhc3VyZWQgZXh0aW5jdGlvbiBhbmQgcHJvZHVjdGl2aXR5IG9mIGZhbWlsaWVzIGRlcml2ZWQgZnJvbSAzNiBkaWZmZXJlbnQgY3Jvc3Nlcy4gQ3Jvc3NlcyB3ZXJlIG9ubHkgY29uZHVjdGVkIGJldHdlZW4gc3RyYWlucyB0aGF0IGV4cGVyaWVuY2VkIHRoZSBzYW1lIGV2b2x1dGlvbiB0cmVhdG1lbnQuIFRoaXMgY29sdW1uIHNob3dzIHRoZSBzdHJhaW4gdGhhdCB0aGUgZm91bmRpbmcgbWFsZSBvZiB0aGUgbGluZWFnZSB3YXMgZGVyaXZlZCBmcm9tLgoKYENyb3NzYDogYW4gaWRlbnRpZnlpbmcgSUQgZm9yIGVhY2ggb2YgdGhlIDM2IGNvbWJpbmF0aW9ucyBvZiBgTW90aGVyIHN0cmFpbmAgYW5kIGBGYXRoZXIgc3RyYWluYC4gCgpgTGluZWFnZWA6IGxpbmVzIG9mIGZsaWVzIGZvdW5kZWQgYnkgc2luZ2xlIGluc2VtaW5hdGVkIGZlbWFsZXMgaW4gZ2VuZXJhdGlvbiB6ZXJvLiBXZSBnZW5lcmF0ZWQgdGhlIG5leHQgZ2VuZXJhdGlvbiBvZiBlYWNoIGxpbmVhZ2UgYnkgY3Jvc3NpbmcgYSBzaW5nbGUgZnVsbC1zaWJsaW5nIGR5YWQuCgpgQmxvY2tgOiB0aGUgZXhwZXJpbWVudCB3YXMgcnVuIGluIDIgZGlzdGluY3QgYmxvY2tzLCB1c2luZyBmbGllcyBzZXBhcmF0ZWQgYnkgOSBnZW5lcmF0aW9ucy4gQmxvY2sgMSByYW4gZm9yIDI5IGdlbmVyYXRpb25zLCB3aGVyZWFzIEJsb2NrIDIgcmFuIGZvciAyMCBnZW5lcmF0aW9ucy4KCmBFdm9sdXRpb25fdHJlYXRtZW50YDogdGhlIHN0cmFpbnMgaGFkIGJlZW4gZXhwb3NlZCB0byBvbmUgb2YgdGhyZWUgZXZvbHV0aW9uYXJ5IGNvbmRpdGlvbnMgZm9yIDIwLTI5IGdlbmVyYXRpb25zOiBhIGZlbWFsZS1saW1pdGVkIHJlc3BvbnNlIHRvIHNlbGVjdGlvbiwgYSBtYWxlLWxpbWl0ZWQgcmVzcG9uc2UgYW5kIGEgY29udHJvbCBjb25kaXRpb24gd2hlcmUgYW4gZXZvbHV0aW9uYXJ5IHJlc3BvbnNlIG9jY3VycmVkIGluIGJvdGggc2V4ZXMuCgpgR2Vuc190b19leHRpbmN0aW9uYDogdGhlIG51bWJlciBvZiBnZW5lcmF0aW9ucyB0aGUgbGluZWFnZSBzdXJ2aXZlZCB1bnRpbCBpdCB3ZW50IGV4dGluY3QuCgpgR2VuXzE6MjlgOiBhIDEgaW5kaWNhdGVzIHRoZSBsaW5lYWdlIHdhcyBleHRhbnQgZm9yIHRoZSBnZW5lcmF0aW9uIGluIHF1ZXN0aW9uLCB3aGlsZSBhIDAgaW5kaWNhdGVzIGV4dGluY3Rpb24uIE5vdGUgdGhhdCB3ZSBjb250aW51ZWQgcHJvcGFnYXRpbmcgc3Vydml2aW5nIGxpbmVhZ2VzIGZyb20gQmxvY2sgMSB1bnRpbCBnZW5lcmF0aW9uIDI5LCB3aGljaCBjb2luY2lkZWQgd2l0aCBnZW5lcmF0aW9uIDIwIGZvciBsaW5lYWdlcyBiZWxvbmdpbmcgdG8gdGhlIHNlY29uZCBCbG9jay4KCmBDZW5zb3JlZGA6IGlmIHRoZSBsaW5lYWdlIDEpIGVuZGVkIGJlY2F1c2UgZmxpZXMgZXNjYXBlZCBvciB3ZXJlIGtpbGxlZCBieSBzb21ldGhpbmcgdW5yZWxhdGVkIHRvIHRoZSBleHBlcmltZW50LCAyKSB3ZW50IGV4dGluY3QgYmVjYXVzZSBvZiBicmVlZGluZyBmZW1hbGUgbW9ydGFsaXR5IG9yIDMpIHdhcyBleHRhbnQgaW4gdGhlIGZpbmFsIGdlbmVyYXRpb24gb2YgdGhlIGV4cGVyaW1lbnQsIHRoZW4gd2UgY29kZWQgYSB2YWx1ZSBvZiAxLiBJZiB0aGUgbGluZWFnZSB3ZW50IGV4dGluY3QsIHdlIGNvZGVkIGEgdmFsdWUgb2YgMC4gVGhpcyBhbGxvd3MgdXMgdG8gcmlnaHQgY2Vuc29yIHRoZSBkYXRhIGFzIHBlciB0aGUgYGJybXNgIHN5bnRheCwgdGhlcmVieSBwcmVzZXJ2aW5nIHRoZSBpbmZvcm1hdGlvbiB0aGVzZSBjZW5zb3JlZCBjYXNlcyBwcm92aWRlIG9uIGV4dGluY3Rpb24uCgokfiQKCiMjIyBNb2RlbGxpbmcgYXBwcm9hY2gKCiR+JAoKV2UgZml0IGEgd2VpYnVsbCBzdXJ2aXZhbCBtb2RlbCB0byBlc3RpbWF0ZSBcbGFtYmRhLCB0aGUgZXh0aW5jdGlvbiByYXRlIG9mIHRoZSBsaW5lYWdlcyB1c2VkIGluIG91ciBleHBlcmltZW50LiBUaGUgd2VpYnVsbCBtb2RlbCBpcyBhbiBleHRlbnNpb24gb2YgYW4gZXhwb25lbnRpYWwgZGVjYXkgbW9kZWwsIGFuZCBpbmNsdWRlcyBhbiBhZGRpdGlvbmFsIHNoYXBlIHBhcmFtZXRlciwgd2hpY2ggYWxsb3dzIFxsYW1iZGEgdG8gdmFyeSBhY3Jvc3MgZ2VuZXJhdGlvbnMgb2YgaW5icmVlZGluZy4gCgoqKlJlc3BvbnNlIHZhcmlhYmxlKioKCmBHZW5zX3RvX2V4dGluY3RgIGlzIG91ciByZXNwb25zZSAtIGEgY29udGludW91cyB2YXJpYWJsZSB0aGF0IHJ1bnMgZnJvbSAxIHRvIDMwIGdlbmVyYXRpb25zLiBOb3RlIHRoYXQgd2UgbWVhc3VyZWQgZXh0aW5jdGlvbiB1cCB1bnRpbCBnZW5lcmF0aW9uIDI5IGluIEJsb2NrIDEgYW5kIGdlbmVyYXRpb24gMjAgaW4gQmxvY2sgMi4gQSB2YWx1ZSBvZiAzMCBpbmRpY2F0ZXMgdGhhdCB0aGUgbGluZWFnZSB3YXMgZXh0YW50IGF0IHRoZSBlbmQgb2YgdGhlIGV4cGVyaW1lbnQgaW4gQmxvY2sgMSwgd2hpbGUgYSB2YWx1ZSBvZiAyMSBpbmRpY2F0ZXMgdGhpcyBpbiBCbG9jayAyLiBXZSBhbHNvIGluY2x1ZGUgcmlnaHQgY2Vuc29yaW5nLCB0byBhY2NvdW50IGZvciBsaW5lYWdlcyBleHRhbnQgYXQgdGhlIGVuZCBvZiB0aGUgZXhwZXJpbWVudCwgb3IgdGhhdCB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgZXhwZXJpbWVudCBieSBhIGhhbmRsaW5nIGVycm9yLiBDZW5zb3JpbmcgZW5hYmxlcyB0aGUgaW5jbHVzaW9uIG9mIHRoaXMgJ2luY29tcGxldGUnIGRhdGEgaW4gdGhlIG1vZGVsLiAKCioqRml4ZWQgZWZmZWN0cyoqCgpgRXZvbHV0aW9uX3RyZWF0bWVudGA6IHdlIGluY2x1ZGUgdGhpcyB0byB0ZXN0IGZvciBhIGNhdXNhbCBlZmZlY3Qgb2Ygc2V4LWxpbWl0ZWQgZXhwZXJpbWVudGFsIGV2b2x1dGlvbiBvbiBtdXRhdGlvbiBsb2FkLiAKCmBCbG9ja2A6IGV4dGluY3Rpb24gcmF0ZSBtaWdodCBkaWZmZXIgYmV0d2VlbiB0aGUgYmxvY2tzIHdlIHNwbGl0IG91ciBleHBlcmltZW50IHVwIGludG8gZS5nLiBiZWNhdXNlIG9mIG1pY3JvdmFyaWF0aW9uIGluIHRoZSBsYWIgYnJvdWdodCBhYm91dCBiZWNhdXNlIG9mIGEgY2hhbmdlIG9mIHNlYXNvbiwgc2xpZ2h0IGluY29uc2lzdGVuY2llcyBpbiBfRHJvc29waGlsYV8gZm9vZCBjb25zaXN0ZW5jeSBldGMuCgoqKlZhcnlpbmcvUmFuZG9tIGVmZmVjdHMqKgoKYENyb3NzYDogd2UgaW5pdGlhdGVkIGVhY2ggbGluZWFnZSBieSBjcm9zc2luZyB0d28gc3RyYWlucyBiZWxvbmdpbmcgdG8gdGhlIHNhbWUgZXZvbHV0aW9uIHRyZWF0bWVudC4gVGhlcmUgd2VyZSAxMiBsZXZlbHMgb2YgY3Jvc3MgbmVzdGVkIHdpdGhpbiBldm9sdXRpb24gdHJlYXRtZW50LCBmb3IgYSB0b3RhbCBvZiAzNiBjcm9zc2VzLiBXZSBrZXB0IGxpbmVhZ2VzIGZyb20gdGhlIHNhbWUgYENyb3NzYCBhbmQgYEJsb2NrYCBpbiB0aGUgc2FtZSBjb2x1bW4gb2YgdGhlIF9Ecm9zb3BoaWxhXyB2aWFsIHRyYXlzLCBzbyBpbmN1ZGluZyB0aGlzIHZhcmlhYmxlIGFsc28gY29udHJvbHMgZm9yIG1pY3JvLWVudmlyb25tZW50YWwgdmFyaWF0aW9uIGNhdXNlZCBieSB3aXRoaW4tdHJheSBwb3NpdGlvbi4gV2UgdXNlZCB0aGlzIHJhbmRvbSBlZmZlY3QgaW4gb3VyIGZpcnN0IG1vZGVsLgoKYE1vdGhlcl9zdHJhaW5gIGFuZCBgRmF0aGVyX3N0cmFpbmA6IFVzZWQgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gYENyb3NzYCBpbiBvdXIgc2Vjb25kIG1vZGVsLiBJbiB0aGlzIGNhc2UsIHdlIGZpdCBhIG11bHRpLW1lbWJlcnNoaXAgbW9kZWwsIHdoZXJlIGVhY2ggbGluZWFnZSBzaW11bHRhbmVvdXNseSBiZWxvbmdzIHRvIHR3byBsZXZlbHMgb2YgdGhlIGBDcm9zc2AgcmFuZG9tIGVmZmVjdC4gVGhhdCBpcywgZWFjaCBsaW5lYWdlIHdhcyBmb3VuZGVkIG15IGEgbW90aGVyIGZyb20gJHN0cmFpbl9pJCBhbmQgYSBmYXRoZXIgZnJvbSAkc3RyYWluX2okIGFuZCB0aGV5IHRoZXJlZm9yZSBhbHdheXMgYmVsb25nIHRvIHR3byBsZXZlbHMgb2Ygc3RyYWluLiAKCioqTXVsdGktbWVtYmVyc2hpcCB2cyBzaW5nbGUtbWVtYmVyc2hpcCoqCgpXaGlsZSB0aGUgbXVsdGktbWVtYmVyc2hpcCBhcHByb2FjaCBtYXkgaW5pdGlhbGx5IHNlZW0gdGhlIG1vcmUgcG93ZXJmdWwgb2YgdGhlIHR3byByYW5kb20gZWZmZWN0IHN0cnVjdHVyZXMsIHdlIGZhdm91ciB0aGUgc2luZ2xlLW1lbWJlcnNoaXAgYXBwcm9hY2ggZm9yIHNldmVyYWwgcmVhc29ucy4gRmlyc3QsIG91ciBwcmltYXJ5IGFpbSBpcyB0byBlc3RpbWF0ZSB0aGUgb3ZlcmFsbCBjYXVzYWwgZWZmZWN0IG9mIGV2b2x1dGlvbiB0cmVhdG1lbnQgb24gZ2VuZXJhdGlvbnMgdG8gZXh0aW5jdGlvbiwgcmF0aGVyIHRoYW4gdGhhdCBvZiBlYWNoIHN0cmFpbiAobmVzdGVkIHdpdGhpbiBldm9sdXRpb24gdHJlYXRtZW50KS4gR2l2ZW4gdGhhdCB3ZSBiYWxhbmNlZCBvdXIgY3Jvc3NpbmcgZGVzaWduIHNvIHRoYXQgZWFjaCBzdHJhaW4gaXMgZXF1YWxseSByZXByZXNlbnRlZCBpbiB0aGUgZXhwZXJpbWVudCwgZXN0aW1hdGlvbiBmb3IgZWFjaCBzdHJhaW4gaXMgbm90IGludGVncmFsLiBTZWNvbmQsIENyb3NzIGNhcHR1cmVzIG51aXNhbmNlIGVudmlyb25tZW50YWwgdmFyaWF0aW9uIHRoYXQgU3RyYWluIGRvZXMgbm90LiBXZSBkaXN0cmlidXRlZCBsaW5lYWdlcyB0aHJvdWdob3V0IHRocmVlIF9Ecm9zb3BoaWxhXyB2aWFsIHRyYXlzIGJ5IHBsYWNpbmcgbGluZWFnZXMgZnJvbSB0aGUgc2FtZSBjcm9zcyBpbiB0aGUgc2FtZSBjb2x1bW4uIEFjcm9zcyB0aGUgY29sdW1ucyB3ZSBzcGxpdCBsaW5lYWdlcyB1cCBieSBldm9sdXRpb24gdHJlYXRtZW50LCBzdWNoIHRoYXQgY29sdW1uIG9uZSBjb250YWluZWQgbGluZWFnZXMgZnJvbSB0aGUgZmVtYWxlLWxpbWl0ZWQgdHJlYXRtZW50LCBjb2x1bW4gdHdvIGNvbnRhaW5lZCBsaW5lYWdlcyBmcm9tIHRoZSBtYWxlLWxpbWl0ZWQgdHJlYXRtZW50IGFuZCBjb2x1bW4gdGhyZWUgY29udGFpbmVkIGxpbmVhZ2VzIGZyb20gdGhlIGNvbnRyb2wgdHJlYXRtZW50LiBXZSByZXBlYXRlZCB0aGlzIHBhdHRlcm4gdW50aWwgYWxsIDM2IGNyb3NzZXMgZmlsbGVkIGEgY29sdW1uLiBBcyBhIHN0cmFpbiBpcyB1c2VkIGluIG11bHRpcGxlIGNyb3NzZXMsIGl0IGlzIHdpZGVseSBkaXN0aXJidXRlZCB0aHJvdWdob3V0IHRoZSB0cmF5cyBhbmQgdGhlcmVmb3JlIGRvZXMgbm90IGNhcHR1cmUgYSBsb2NhdGlvbiBlZmZlY3QgbGlrZSBjcm9zcyBkb2VzLiBXZSBhcmUgb2YgdGhlIG9waW5pb24gdGhhdCBjb250cm9sbGluZyBmb3IgdGhpcyBlbnZpcm9ubWVudGFsIHZhcmlhdGlvbiBpcyBvZiBncmVhdGVyIGltcG9ydGFuY2UgdGhhbiBzdHJhaW4gbGV2ZWwgZGlmZmVyZW5jZXMgaW4gbXV0YXRpb24gbG9hZCwgd2hpY2ggYm90aCBjcm9zcyBhbmQgZXZvbHV0aW9uIHRyZWF0bWVudCBhbHNvIGNvbnRhaW4gaW5mb3JtYXRpb24gZm9yLgoKRmluYWxseSwgd2UgZml0IGJvdGggbW9kZWxzIGFuZCB1c2UgbGVhdmUgb25lIG91dCAoTE9PKSBjcm9zcyB2YWxpZGF0aW9uIHRvIGZvcm1hbGx5IGFzc2VzcyB3aGljaCBtb2RlbCBoYXMgYmV0dGVyIGV4cGVjdGVkIHByZWRpY3RpdmUgYWNjdXJhY3ksIGJvdGggaW4gYW5kIG91dCBvZiBzYW1wbGUuCgoqKlByaW9ycyoqCgpXZSBmaXQgbW9kZXJhdGVseSBpbmZvcm1hdGl2ZSBwcmlvcnMsIHdpdGggdGhlIGFpbSB0byByZWd1bGFyaXNlIG91ciBwb3N0ZXJpb3IgZXN0aW1hdGVzIGFuZCBpbXByb3ZlIG1vZGVsIGZpdHRpbmcgYnkgcnVsaW5nIG91dCBub24tc2Vuc2ljYWwgdmFsdWVzLgoKTm90ZSB0aGF0IGVhY2ggb2YgdGhlc2UgcHJpb3JzIGlzIGV4cHJlc3NlZCBvbiB0aGUgbG9nIHNjYWxlLCBkdWUgdG8gdGhlIHdlaWJ1bGwgbG9nIGxpbmsuCgokXGFscGhhJCAodGhlIGludGVyY2VwdHMpIH4gTm9ybWFsKCRcbXUkID0gMCwgJFxzaWdtYSQgPSAxKQoKJFxiZXRhJCAodGhlIGZpeGVkIGVmZmVjdHMpIH4gTm9ybWFsKCRcbXUkID0gMCwgJFxzaWdtYSQgPSAxKSAKCiRcc2lnbWEkIH4gRXhwb25lbnRpYWwoMSkKCiRrJCAoVGhlIHdlaWJ1bGwgc2hhcGUgcGFyYW1ldGVyKSB+IE5vcm1hbCgkXG11JCA9IDAsICRcc2lnbWEkID0gMSkgCgoKIyMjIEZpdCB0aGUgbW9kZWxzCgpgYGB7cn0KCmV4dGluY3Rpb25fbW9kZWxfc20gPC0KICBicm0oZGF0YSA9IGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCwKICAgICAgZmFtaWx5ID0gd2VpYnVsbCwKICAgICAgYmYoR2Vuc190b19leHRpbmN0IHwgY2VucyhDZW5zb3JlZCkgfiAxICsgRXZvbHV0aW9uX3RyZWF0bWVudCArIEJsb2NrICsgKDF8Q3Jvc3MpLAogICAgICAgICBzaGFwZSB+IDEgKyBFdm9sdXRpb25fdHJlYXRtZW50ICsgQmxvY2spLAogICAgICAjIHRoaXMgaW50ZXJjZXB0IHByaW9yIHByZWRpY3RzIGFuIGFwcHJvcHJpYXRlIHN0YXJ0aW5nIHBvaW50IGZvciBwZXIgZ2VuIGV4dGluY3Rpb24gcmF0ZSBvbiB0aGUgbG9nIHNjYWxlCiAgICAgIHByaW9yID0gYyhwcmlvcihnYW1tYSg1LCAzLjUpLCBjbGFzcyA9IEludGVyY2VwdCksICAKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSBiKSwKICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgxLCAwLjUpLCBjbGFzcyA9IGIsIGRwYXIgPSBzaGFwZSkpLCAKICAgICAgaXRlciA9IDgwMDAsIHdhcm11cCA9IDQwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwKICAgICAgc2VlZCA9IDEsIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gLjksIG1heF90cmVlZGVwdGggPSAxMCksCiAgICAgICBmaWxlID0gIkZpdHMvZXh0aW5jdGlvbl9tb2RlbF9tb3J0YWxpdHkiKQoKZXh0aW5jdGlvbl9tb2RlbF9zbSA8LSBhZGRfY3JpdGVyaW9uKGV4dGluY3Rpb25fbW9kZWxfc20sIGNyaXRlcmlvbiA9ICJsb28iLCBtb21lbnRfbWF0Y2ggPSBUUlVFKQoKIyB0aGUgbW9kZWwgZG9lcyBub3QgY29udmVyZ2Ugd2hlbiB3ZSB0cnkgYW5kIGZpdCBhIHRyZWF0bWVudCAqIGJsb2NrIGludGVyYWN0aW9uCgpleHRpbmN0aW9uX21vZGVsX21tIDwtCiAgYnJtKGRhdGEgPSBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQsCiAgICAgIGZhbWlseSA9IHdlaWJ1bGwsCiAgICAgIGJmKEdlbnNfdG9fZXh0aW5jdCB8IGNlbnMoQ2Vuc29yZWQpIH4gMSArIEV2b2x1dGlvbl90cmVhdG1lbnQgKyBCbG9jayArICgxfG1tKE1vdGhlcl9zdHJhaW4sIEZhdGhlcl9zdHJhaW4pKSwKICAgICAgc2hhcGUgfiAxICsgRXZvbHV0aW9uX3RyZWF0bWVudCArIEJsb2NrKSwKICAgICAgIyB0aGlzIGludGVyY2VwdCBwcmlvciBwcmVkaWN0cyBhbiBhcHByb3ByaWF0ZSBzdGFydGluZyBwb2ludCBmb3IgcGVyIGdlbiBleHRpbmN0aW9uIHJhdGUgb24gdGhlIGxvZyBzY2FsZQogICAgICBwcmlvciA9IGMocHJpb3IoZ2FtbWEoNSwgMy41KSwgY2xhc3MgPSBJbnRlcmNlcHQpLCAKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSBiKSwKICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgxLCAwLjUpLCBjbGFzcyA9IGIsIGRwYXIgPSBzaGFwZSkpLCAKICAgICAgaXRlciA9IDgwMDAsIHdhcm11cCA9IDQwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwKICAgICAgc2VlZCA9IDEsIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45LCBtYXhfdHJlZWRlcHRoID0gMTUpLAogICAgICBmaWxlID0gIkZpdHMvZXh0aW5jdGlvbl9tb2RlbF9tbSIpCgpleHRpbmN0aW9uX21vZGVsX21tIDwtIGFkZF9jcml0ZXJpb24oZXh0aW5jdGlvbl9tb2RlbF9tbSwgY3JpdGVyaW9uID0gImxvbyIpCgpgYGAKCiR+JAoKIyMjIE1vZGVsIGRpYWdub3N0aWNzCgokfiQKCkNvbXBhcmUgbW9kZWxzIHVzaW5nIGBMT09gLCBhIGJheWVzaWFuIGluZm9ybWF0aW9uIGNyaXRlcmlhCgpgYGB7cn0KbG9vX2NvbXBhcmUoZXh0aW5jdGlvbl9tb2RlbF9zbSwgZXh0aW5jdGlvbl9tb2RlbF9tbSkgICU+JSAKICBrYWJsZShkaWdpdHMgPSAzKSAlPiUgCiAga2FibGVfc3R5bGluZygpCmBgYAoKVGhlIHNpbmdsZS1tZW1iZXJzaGlwIG1vZGVsIHBlcmZvcm1zICpzbGlnaHRseSogYmV0dGVyLiBXZSBwcmVzZW50IHJlc3VsdHMgZnJvbSB0aGlzIG1vZGVsLgoKTGV0cyBzZWUgaG93IHRoZSBtb2RlbCByZWNhcGl0dWxhdGVzIHRoZSBkYXRhCgpgYGB7cn0KcHBfY2hlY2soZXh0aW5jdGlvbl9tb2RlbF9zbSwgdHlwZSA9ICJoaXN0IiwgbmRyYXdzID0gMTEsIGJpbndpZHRoID0gMSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgokfiQKCiMjIyBJbnRlcnByZXRpbmcgbW9kZWwgb3V0cHV0CgokfiQKCldlIGNhbiBpbml0aWFsbHkgaWdub3JlIHRoZSBgc2hhcGVgIHBhcmFtZXRlciBhbmQgZmluZCB0aGUgbWVhbiByYXRlIG9mIGV4dGluY3Rpb24sIGF2ZXJhZ2VkIGFjcm9zcyBhbGwgZ2VuZXJhdGlvbnMsIHVzaW5nIHRoZSBlcXVhdGlvbgoKJFxsYW1iZGE9IFxmcmFjezF9e2VeXG11fSQKCkZpcnN0IGZpbmQgZGlzdHJpYnV0aW9ucyBvZiAkXG11JCBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgdHJlYXRtZW50cy4KCmBgYHtyfQoKaW52ZXJzZV9yYXRlX3dlaWJ1bGwgPC0KICBleHRpbmN0aW9uX21vZGVsX3NtICU+JSAKICBhc19kcmF3c19kZigpICU+JSAKICB0cmFuc211dGUoYENvbnRyb2wgQjFgID0gYl9JbnRlcmNlcHQsIAogICAgICAgICBgRmVtYWxlX2xpbWl0ZWQgQjFgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUsCiAgICAgICAgIGBNYWxlX2xpbWl0ZWQgQjFgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRNYWxlLAogICAgICAgICBgQ29udHJvbCBCMmAgPSBiX0ludGVyY2VwdCArIGJfQmxvY2syLCAKICAgICAgICAgYEZlbWFsZV9saW1pdGVkIEIyYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50RmVtYWxlICsgYl9CbG9jazIsCiAgICAgICAgIGBNYWxlX2xpbWl0ZWQgQjJgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRNYWxlICsgYl9CbG9jazIpCgpgYGAKCk5vdyBsZXRzIHBsdWcgdGhlc2UgZGlzdHJpYnV0aW9ucyBpbnRvIHRoZSBlcXVhdGlvbiB0byBmaW5kIG1lYW4gZXN0aW1hdGVzIG9mICRcbGFtYmRhJC4KCmBgYHtyfQogIGludmVyc2VfcmF0ZV93ZWlidWxsICU+JSAKICBtdXRhdGUoYWNyb3NzKDE6NiwgfjEgLyBleHAoLngpKSkgJT4lIAogIG11dGF0ZShhY3Jvc3MoZXZlcnl0aGluZygpLCB+bWVhbigueCkpKSAlPiUgCiAgZGlzdGluY3QoKQpgYGAKClRoaXMgaXMgdGhlIHJhdGUgb2YgZXh0aW5jdGlvbiBwZXIgZ2VuZXJhdGlvbiwgYXZlcmFnZWQgYWNyb3NzIGFsbCBnZW5lcmF0aW9ucy4gSG93ZXZlciwgdGhlIHdlaWJ1bGwgZmFtaWx5IGFsbG93cyBhIGR5bmFtaWMgcmF0ZSByYXRoZXIgdGhlIHRoZSBjb25zdGFudCByYXRlIHRoYXQgdGhlIGV4cG9uZW50aWFsIGNvbnN0cmFpbnMgaXQgdG8uCgpGb2xsb3dpbmcgdGhpcyBbcG9zdF0oaHR0cHM6Ly9kaXNjb3Vyc2UubWMtc3Rhbi5vcmcvdC9lc3RpbWF0aW5nLXN1cnZpdmFsLWN1cnZlcy13aXRoLXdlaWJ1bGxsLW1vZGVsLzY0NzUvMiksIHRoZSB3ZWlidWxsIHN1cnZpdmFsIGZ1bmN0aW9uIGNhbiBiZSBmb3VuZCB1c2luZyB0aGUgZm9sbG93aW5nIHRyYW5zZm9ybWF0aW9uOgoKJFxsYW1iZGE9IFxmcmFje2VeXG11fXtcZ2FtbWEoMSArIFxmcmFjezF9e2t9KX0kCgp3aGVyZSAkayQgaXMgdGhlIHNoYXBlIHBhcmFtZXRlciBlc3RpbWF0ZWQgaW4gYGJybXNgCgpUaGVuIHdlIGNhbiBmaW5kIHN1cnZpdmFsIGF0IGdlbmVyYXRpb24gJHQkIHVzaW5nCgokUyA9IGVeey0oXGZyYWN7dH17XGxhbWJkYX0pXmt9JAoKV2UgcGx1ZyBpbiBhIHZlY3RvciB3aXRoIDE2MDAwIGRyYXdzIGZyb20gdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gZm9yIDEpIFxtdSBvZiBlYWNoIGluaGVyaXRhbmNlIHRyZWF0bWVudCBhbmQgMikgJGskIHRoZSBzaGFwZSBwYXJhbWV0ZXIgdG8gZmluZCBkaXN0cmlidXRpb25zIG9mIHRoZSBwcm9wb3J0aW9uIG9mIHN1cnZpdmluZyBsaW5lYWdlcyBhdCBlYWNoIGdlbmVyYXRpb24uCgpgYGB7cn0KCiMgRmluZCBsYW1iZGEgZm9yIHRoZSB0aHJlZSB0cmVhdG1lbnRzLiAKCmxhbWJkYV93ZWlidWxsIDwtCiAgZXh0aW5jdGlvbl9tb2RlbF9zbSAlPiUgCiAgYXNfZHJhd3NfZGYoKSAlPiUgCiAgdHJhbnNtdXRlKGBDb250cm9sIEIxYCA9IGJfSW50ZXJjZXB0LCAKICAgICAgICAgICAgYEZlbWFsZV9saW1pdGVkIEIxYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50RmVtYWxlLAogICAgICAgICAgICBgTWFsZV9saW1pdGVkIEIxYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50TWFsZSwKICAgICAgICAgICAgYENvbnRyb2wgQjJgID0gYl9JbnRlcmNlcHQgKyBiX0Jsb2NrMiwgCiAgICAgICAgICAgIGBGZW1hbGVfbGltaXRlZCBCMmAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudEZlbWFsZSArIGJfQmxvY2syLAogICAgICAgICAgICBgTWFsZV9saW1pdGVkIEIyYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50TWFsZSArIGJfQmxvY2syLAogICAgICAgICAgICBzaGFwZV9jb250cm9sX0IxID0gZXhwKGJfc2hhcGVfSW50ZXJjZXB0KSwKICAgICAgICAgICAgc2hhcGVfZmVtYWxlX0IxID0gZXhwKGJfc2hhcGVfSW50ZXJjZXB0ICsgYl9zaGFwZV9Fdm9sdXRpb25fdHJlYXRtZW50RmVtYWxlKSwKICAgICAgICAgICAgc2hhcGVfbWFsZV9CMSA9IGV4cChiX3NoYXBlX0ludGVyY2VwdCArIGJfc2hhcGVfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUpLAogICAgICAgICAgICBzaGFwZV9jb250cm9sX0IyID0gZXhwKGJfc2hhcGVfSW50ZXJjZXB0ICsgYl9zaGFwZV9CbG9jazIpLAogICAgICAgICAgICBzaGFwZV9mZW1hbGVfQjIgPSBleHAoYl9zaGFwZV9JbnRlcmNlcHQgKyBiX3NoYXBlX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUgKyBiX3NoYXBlX0Jsb2NrMiksCiAgICAgICAgICAgIHNoYXBlX21hbGVfQjIgPSBleHAoYl9zaGFwZV9JbnRlcmNlcHQgKyBiX3NoYXBlX0V2b2x1dGlvbl90cmVhdG1lbnRNYWxlICsgYl9zaGFwZV9CbG9jazIpKSAlPiUgCiAgbXV0YXRlKENvbnRyb2xfbGFtYmRhX0IxID0gZXhwKGBDb250cm9sIEIxYCkgLyBnYW1tYSgxICsgMS9zaGFwZV9jb250cm9sX0IxKSwKICAgICAgICAgRmVtYWxlX2xhbWJkYV9CMSA9IGV4cChgRmVtYWxlX2xpbWl0ZWQgQjFgKSAvIGdhbW1hKDEgKyAxL3NoYXBlX2ZlbWFsZV9CMSksCiAgICAgICAgIE1hbGVfbGFtYmRhX0IxID0gZXhwKGBNYWxlX2xpbWl0ZWQgQjFgKSAvIGdhbW1hKDEgKyAxL3NoYXBlX21hbGVfQjEpLAogICAgICAgICBDb250cm9sX2xhbWJkYV9CMiA9IGV4cChgQ29udHJvbCBCMmApIC8gZ2FtbWEoMSArIDEvc2hhcGVfY29udHJvbF9CMiksCiAgICAgICAgIEZlbWFsZV9sYW1iZGFfQjIgPSBleHAoYEZlbWFsZV9saW1pdGVkIEIyYCkgLyBnYW1tYSgxICsgMS9zaGFwZV9mZW1hbGVfQjIpLAogICAgICAgICBNYWxlX2xhbWJkYV9CMiA9IGV4cChgTWFsZV9saW1pdGVkIEIyYCkgLyBnYW1tYSgxICsgMS9zaGFwZV9tYWxlX0IyKSkgJT4lIAogIHNlbGVjdChjb250YWlucyhjKCJsYW1iZGEiLCAic2hhcGUiKSkpCgojIE5vdyBmaW5kIHN1cnZpdmFsIHByb3BvcnRpb24gYXQgZ2VuZXJhdGlvbnMgMS0yOQoKV2VpYnVsbF9zdXJ2aXZhbF9jdXJ2ZSA8LSAKICBsYW1iZGFfd2VpYnVsbCAlPiUgCiAgbXV0YXRlKCNCbG9jayAxCiAgICBDb250cm9sXzBfQjEgID0gZXhwKC0oMC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksICAKICAgIENvbnRyb2xfMV9CMSAgPSBleHAoLSgxL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMl9CMSAgPSBleHAoLSgyL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfM19CMSAgPSBleHAoLSgzL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfNF9CMSAgPSBleHAoLSg0L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfNV9CMSAgPSBleHAoLSg1L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfNl9CMSAgPSBleHAoLSg2L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfN19CMSAgPSBleHAoLSg3L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfOF9CMSA9IGV4cCgtKDgvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF85X0IxID0gZXhwKC0oOS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzEwX0IxID0gZXhwKC0oMTAvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xMV9CMSA9IGV4cCgtKDExL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTJfQjEgPSBleHAoLSgxMi9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzEzX0IxID0gZXhwKC0oMTMvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xNF9CMSA9IGV4cCgtKDE0L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTVfQjEgPSBleHAoLSgxNS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzE2X0IxID0gZXhwKC0oMTYvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xN19CMSA9IGV4cCgtKDE3L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMThfQjEgPSBleHAoLSgxOC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzE5X0IxID0gZXhwKC0oMTkvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yMF9CMSA9IGV4cCgtKDIwL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjFfQjEgPSBleHAoLSgyMS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzIyX0IxID0gZXhwKC0oMjIvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yM19CMSA9IGV4cCgtKDIzL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjRfQjEgPSBleHAoLSgyNC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzI1X0IxID0gZXhwKC0oMjUvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yNl9CMSA9IGV4cCgtKDI2L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjdfQjEgPSBleHAoLSgyNy9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzI4X0IxID0gZXhwKC0oMjgvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yOV9CMSA9IGV4cCgtKDI5L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIEZlbWFsZV8wX0IxICA9IGV4cCgtKDAvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xX0IxICA9IGV4cCgtKDEvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yX0IxICA9IGV4cCgtKDIvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8zX0IxICA9IGV4cCgtKDMvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV80X0IxICA9IGV4cCgtKDQvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV81X0IxICA9IGV4cCgtKDUvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV82X0IxICA9IGV4cCgtKDYvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV83X0IxICA9IGV4cCgtKDcvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV84X0IxICA9IGV4cCgtKDgvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV85X0IxICA9IGV4cCgtKDkvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xMF9CMSAgPSBleHAoLSgxMC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzExX0IxICA9IGV4cCgtKDExL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMTJfQjEgID0gZXhwKC0oMTIvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xM19CMSAgPSBleHAoLSgxMy9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzE0X0IxICA9IGV4cCgtKDE0L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMTVfQjEgID0gZXhwKC0oMTUvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xNl9CMSAgPSBleHAoLSgxNi9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzE3X0IxICA9IGV4cCgtKDE3L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMThfQjEgID0gZXhwKC0oMTgvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xOV9CMSAgPSBleHAoLSgxOS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzIwX0IxICA9IGV4cCgtKDIwL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjFfQjEgPSBleHAoLSgyMS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzIyX0IxID0gZXhwKC0oMjIvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yM19CMSA9IGV4cCgtKDIzL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjRfQjEgPSBleHAoLSgyNC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzI1X0IxID0gZXhwKC0oMjUvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yNl9CMSA9IGV4cCgtKDI2L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjdfQjEgPSBleHAoLSgyNy9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzI4X0IxID0gZXhwKC0oMjgvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yOV9CMSA9IGV4cCgtKDI5L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBNYWxlXzBfQjEgICAgID0gZXhwKC0oMC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzFfQjEgICAgID0gZXhwKC0oMS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzJfQjEgICAgID0gZXhwKC0oMi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzNfQjEgICAgID0gZXhwKC0oMy9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzRfQjEgICAgID0gZXhwKC0oNC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzVfQjEgICAgID0gZXhwKC0oNS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzZfQjEgICAgID0gZXhwKC0oNi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzdfQjEgICAgID0gZXhwKC0oNy9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzhfQjEgICAgID0gZXhwKC0oOC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzlfQjEgICAgID0gZXhwKC0oOS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzEwX0IxICAgID0gZXhwKC0oMTAvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xMV9CMSAgICA9IGV4cCgtKDExL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTJfQjEgICAgPSBleHAoLSgxMi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzEzX0IxICAgID0gZXhwKC0oMTMvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xNF9CMSAgICA9IGV4cCgtKDE0L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTVfQjEgICAgPSBleHAoLSgxNS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzE2X0IxICAgID0gZXhwKC0oMTYvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xN19CMSAgICA9IGV4cCgtKDE3L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMThfQjEgICAgPSBleHAoLSgxOC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzE5X0IxICAgID0gZXhwKC0oMTkvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yMF9CMSAgICA9IGV4cCgtKDIwL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjFfQjEgPSBleHAoLSgyMS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzIyX0IxID0gZXhwKC0oMjIvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yM19CMSA9IGV4cCgtKDIzL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjRfQjEgPSBleHAoLSgyNC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzI1X0IxID0gZXhwKC0oMjUvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yNl9CMSA9IGV4cCgtKDI2L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjdfQjEgPSBleHAoLSgyNy9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzI4X0IxID0gZXhwKC0oMjgvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yOV9CMSA9IGV4cCgtKDI5L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgICMgQmxvY2sgMgogICAgQ29udHJvbF8wX0IyICA9IGV4cCgtKDAvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLCAgCiAgICBDb250cm9sXzFfQjIgID0gZXhwKC0oMS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzJfQjIgID0gZXhwKC0oMi9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzNfQjIgID0gZXhwKC0oMy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzRfQjIgID0gZXhwKC0oNC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzVfQjIgID0gZXhwKC0oNS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzZfQjIgID0gZXhwKC0oNi9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzdfQjIgID0gZXhwKC0oNy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzhfQjIgPSBleHAoLSg4L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfOV9CMiA9IGV4cCgtKDkvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xMF9CMiA9IGV4cCgtKDEwL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTFfQjIgPSBleHAoLSgxMS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzEyX0IyID0gZXhwKC0oMTIvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xM19CMiA9IGV4cCgtKDEzL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTRfQjIgPSBleHAoLSgxNC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzE1X0IyID0gZXhwKC0oMTUvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xNl9CMiA9IGV4cCgtKDE2L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTdfQjIgPSBleHAoLSgxNy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzE4X0IyID0gZXhwKC0oMTgvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xOV9CMiA9IGV4cCgtKDE5L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjBfQjIgPSBleHAoLSgyMC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzIxX0IyID0gZXhwKC0oMjEvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yMl9CMiA9IGV4cCgtKDIyL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjNfQjIgPSBleHAoLSgyMy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzI0X0IyID0gZXhwKC0oMjQvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yNV9CMiA9IGV4cCgtKDI1L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjZfQjIgPSBleHAoLSgyNi9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzI3X0IyID0gZXhwKC0oMjcvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yOF9CMiA9IGV4cCgtKDI4L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjlfQjIgPSBleHAoLSgyOS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBGZW1hbGVfMF9CMiAgPSBleHAoLSgwL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMV9CMiAgPSBleHAoLSgxL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMl9CMiAgPSBleHAoLSgyL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfM19CMiAgPSBleHAoLSgzL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfNF9CMiAgPSBleHAoLSg0L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfNV9CMiAgPSBleHAoLSg1L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfNl9CMiAgPSBleHAoLSg2L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfN19CMiAgPSBleHAoLSg3L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfOF9CMiAgPSBleHAoLSg4L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfOV9CMiAgPSBleHAoLSg5L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTBfQjIgID0gZXhwKC0oMTAvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xMV9CMiAgPSBleHAoLSgxMS9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzEyX0IyICA9IGV4cCgtKDEyL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTNfQjIgID0gZXhwKC0oMTMvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xNF9CMiAgPSBleHAoLSgxNC9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzE1X0IyICA9IGV4cCgtKDE1L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTZfQjIgID0gZXhwKC0oMTYvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xN19CMiAgPSBleHAoLSgxNy9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzE4X0IyICA9IGV4cCgtKDE4L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTlfQjIgID0gZXhwKC0oMTkvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yMF9CMiAgPSBleHAoLSgyMC9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzIxX0IyID0gZXhwKC0oMjEvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yMl9CMiA9IGV4cCgtKDIyL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjNfQjIgPSBleHAoLSgyMy9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzI0X0IyID0gZXhwKC0oMjQvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yNV9CMiA9IGV4cCgtKDI1L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjZfQjIgPSBleHAoLSgyNi9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzI3X0IyID0gZXhwKC0oMjcvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yOF9CMiA9IGV4cCgtKDI4L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjlfQjIgPSBleHAoLSgyOS9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgTWFsZV8wX0IyICAgICA9IGV4cCgtKDAvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xX0IyICAgICA9IGV4cCgtKDEvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yX0IyICAgICA9IGV4cCgtKDIvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8zX0IyICAgICA9IGV4cCgtKDMvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV80X0IyICAgICA9IGV4cCgtKDQvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV81X0IyICAgICA9IGV4cCgtKDUvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV82X0IyICAgICA9IGV4cCgtKDYvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV83X0IyICAgICA9IGV4cCgtKDcvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV84X0IyICAgICA9IGV4cCgtKDgvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV85X0IyICAgICA9IGV4cCgtKDkvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xMF9CMiAgICA9IGV4cCgtKDEwL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTFfQjIgICAgPSBleHAoLSgxMS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzEyX0IyICAgID0gZXhwKC0oMTIvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xM19CMiAgICA9IGV4cCgtKDEzL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTRfQjIgICAgPSBleHAoLSgxNC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzE1X0IyICAgID0gZXhwKC0oMTUvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xNl9CMiAgICA9IGV4cCgtKDE2L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTdfQjIgICAgPSBleHAoLSgxNy9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzE4X0IyICAgID0gZXhwKC0oMTgvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xOV9CMiAgICA9IGV4cCgtKDE5L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjBfQjIgICAgPSBleHAoLSgyMC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzIxX0IyID0gZXhwKC0oMjEvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yMl9CMiA9IGV4cCgtKDIyL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjNfQjIgPSBleHAoLSgyMy9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzI0X0IyID0gZXhwKC0oMjQvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yNV9CMiA9IGV4cCgtKDI1L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjZfQjIgPSBleHAoLSgyNi9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzI3X0IyID0gZXhwKC0oMjcvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yOF9CMiA9IGV4cCgtKDI4L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjlfQjIgPSBleHAoLSgyOS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMikpICU+JSAKICBzZWxlY3QoLWMoY29udGFpbnMoYygic2hhcGUiLCAibGFtYmRhIikpKSkKCldlaWJ1bGxfZXh0aW5jdGlvbl9lc3RpbWF0ZXNfbG9uZyA8LQogIFdlaWJ1bGxfc3Vydml2YWxfY3VydmUgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gZXZlcnl0aGluZygpLCBuYW1lc190byA9ICJFdm9sdXRpb24gdHJlYXRtZW50IiwgdmFsdWVzX3RvID0gIlByb3BfbGluZWFnZXNfc3Vydml2aW5nIikgJT4lIAogIHNlcGFyYXRlKGBFdm9sdXRpb24gdHJlYXRtZW50YCwgaW50byA9IGMoIkV2b2x1dGlvbiB0cmVhdG1lbnQiLCAiR2VuZXJhdGlvbiIsICJCbG9jayIpLCBzZXAgPSAiXyIpICU+JSAKICAgIG11dGF0ZShgRXZvbHV0aW9uIHRyZWF0bWVudGAgPSBjYXNlX3doZW4oCiAgICBgRXZvbHV0aW9uIHRyZWF0bWVudGAgPT0gIkZlbWFsZSIgfiAiRmVtYWxlLWxpbWl0ZWQiLAogICAgYEV2b2x1dGlvbiB0cmVhdG1lbnRgID09ICJNYWxlIiB+ICJNYWxlLWxpbWl0ZWQiLAogICAgYEV2b2x1dGlvbiB0cmVhdG1lbnRgID09ICJDb250cm9sIiB+ICJDb250cm9sIgogICkpCgpgYGAKCiR+JAoKIyMjIENyZWF0ZSBGaWd1cmUgMQoKTWFrZSBwYW5lbCBhIG9mIEZpZ3VyZSAxCgpgYGB7cn0KIyBCbG9jayAxCgp3ZWlidWxsX3N1cnZfcGxvdF9CMSA8LSAKICBXZWlidWxsX2V4dGluY3Rpb25fZXN0aW1hdGVzX2xvbmcgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiQjEiKSAlPiUgCiAgZ3JvdXBfYnkoYEV2b2x1dGlvbiB0cmVhdG1lbnRgLCBHZW5lcmF0aW9uKSAlPiUgCiAgdGlkeWJheWVzOjptZWRpYW5fcWkoUHJvcF9saW5lYWdlc19zdXJ2aXZpbmcsIC53aWR0aCA9IDAuNSkgJT4lIAogIG11dGF0ZShHZW5lcmF0aW9uID0gYXMubnVtZXJpYyhHZW5lcmF0aW9uKSkgJT4lIAogIGFycmFuZ2UoR2VuZXJhdGlvbikgJT4lIAogICMgcGxvdCEKICBnZ3Bsb3QoYWVzKHggPSBHZW5lcmF0aW9uKSkgKwogIGdlb21fcmliYm9uKGFlcyh5bWluID0gLmxvd2VyLCB5bWF4ID0gLnVwcGVyLCBmaWxsID0gYEV2b2x1dGlvbiB0cmVhdG1lbnRgKSwKICAgICAgICAgICAgICBhbHBoYSA9IDEvMikgKwogIGdlb21fbGluZShhZXMoeSA9IFByb3BfbGluZWFnZXNfc3Vydml2aW5nLCBjb2xvciA9IGBFdm9sdXRpb24gdHJlYXRtZW50YCksIGxpbmV0eXBlID01LCBsaW5ld2lkdGggPSAwLjgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSwgZ3VpZGUgPSAibm9uZSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCA1LCAxMCwgMTUsIDIwLCAyNSwgMzApLCBleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wMSwgMC4wMSkpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMC4yNSwgLjUsIDAuNzUsIDEpLCBsaW1pdHMgPSAwOjEsIGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLjAxLCAwLjAxKSkpICsKICBsYWJzKHggPSAiR2VuZXJhdGlvbnMgb2YgaW5icmVlZGluZyIsIHkgPSAiUHJvcG9ydGlvbiBvZiBzdXJ2aW5nIGxpbmVhZ2VzIiwgZmlsbCA9ICJTZWxlY3Rpb24gcmVzcG9uc2Vcbmhpc3RvcnkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBsZWdlbmQgYmcKICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvdXIgPSAndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoLjk1LCAuOTUpLAogICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygicmlnaHQiLCAidG9wIiksCiAgICAgICAgbGVnZW5kLmJveC5qdXN0ID0gInJpZ2h0IiwKICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKDYsIDYsIDYsIDYpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpKQoKYGBgCgpXZSBjYW4gYWxzbyBwbG90IHRoZSBtZWFuIGdlbmVyYXRpb25zIHVudGlsIGV4dGluY3Rpb24gZm9yIGVhY2ggZXZvbHV0aW9uIHRyZWF0bWVudC4gU29tZSBkYXRhIHdyYW5nbGluZyBpcyBmaXJzdCBuZWVkZWQuCgpgYGB7cn0KCm5ld19kYXRhIDwtIGV4cGFuZF9ncmlkKAogIEV2b2x1dGlvbl90cmVhdG1lbnQgPSBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQkRXZvbHV0aW9uX3RyZWF0bWVudCwKICBCbG9jayA9IDE6MikgJT4lIAogIGRpc3RpbmN0KEV2b2x1dGlvbl90cmVhdG1lbnQsIEJsb2NrKSAlPiUKICBtdXRhdGUoa2V5ID0gcGFzdGUoIlYiLCAxOm4oKSwgc2VwID0gIiIpKQoKd2VpYnVsbF9lc3RpbWF0ZXMgPC0gCiAgZml0dGVkKGV4dGluY3Rpb25fbW9kZWxfc20sIG5ld2RhdGEgPSBuZXdfZGF0YSwKICAgICAgICAgcmVfZm9ybXVsYSA9IE5BLCBzdW1tYXJ5ID0gRikgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICByZW5hbWUoYEZlbWFsZS1saW1pdGVkXzFgID0gVjEsIGBGZW1hbGUtbGltaXRlZF8yYCA9IFYyLCBgTWFsZS1saW1pdGVkXzFgID0gVjMsIGBNYWxlLWxpbWl0ZWRfMmAgPSBWNCwgQ29udHJvbF8xID0gVjUsIENvbnRyb2xfMiA9IFY2KQoKbWVhbl93ZWlidWxsX2VzdGltYXRlcyA8LSAKICB3ZWlidWxsX2VzdGltYXRlcyAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjYsIG5hbWVzX3RvID0gIkV2b2x1dGlvbiB0cmVhdG1lbnQiLCB2YWx1ZXNfdG8gPSAiZ2VuZXJhdGlvbnMiKSAlPiUgCiAgc2VwYXJhdGUoY29sID0gYEV2b2x1dGlvbiB0cmVhdG1lbnRgLCBpbnRvID0gYygiRXZvbHV0aW9uIHRyZWF0bWVudCIsICJCbG9jayIpLCBzZXAgPSAiXyIpCgoKIyBjYWxjdWxhdGUgY29udHJhc3RzCgp3ZWlidWxsX2NvbnRyYXN0c19CMSA8LQogIHdlaWJ1bGxfZXN0aW1hdGVzICU+JSAKICBtdXRhdGUoYEZlbWFsZSAtIENvbnRyb2xgID0gYEZlbWFsZS1saW1pdGVkXzFgIC0gQ29udHJvbF8xLAogICAgICAgICBgTWFsZSAtIEZlbWFsZWAgPSBgTWFsZS1saW1pdGVkXzFgIC0gYEZlbWFsZS1saW1pdGVkXzFgLAogICAgICAgICBgTWFsZSAtIENvbnRyb2xgID0gYE1hbGUtbGltaXRlZF8xYCAtIENvbnRyb2xfMSkgJT4lIAogIHNlbGVjdCgtYyhgTWFsZS1saW1pdGVkXzFgLCBDb250cm9sXzEsIGBGZW1hbGUtbGltaXRlZF8xYCwKICAgICAgICAgICAgYE1hbGUtbGltaXRlZF8yYCwgQ29udHJvbF8yLCBgRmVtYWxlLWxpbWl0ZWRfMmApKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gIkNvbnRyYXN0IiwgdmFsdWVzX3RvID0gImdlbmVyYXRpb25fZGlmZiIpCgp3ZWlidWxsX2NvbnRyYXN0c19CMiA8LQogIHdlaWJ1bGxfZXN0aW1hdGVzICU+JSAKICBtdXRhdGUoYEZlbWFsZSAtIENvbnRyb2xgID0gYEZlbWFsZS1saW1pdGVkXzJgIC0gQ29udHJvbF8yLAogICAgICAgICBgTWFsZSAtIEZlbWFsZWAgPSBgTWFsZS1saW1pdGVkXzJgIC0gYEZlbWFsZS1saW1pdGVkXzJgLAogICAgICAgICBgTWFsZSAtIENvbnRyb2xgID0gYE1hbGUtbGltaXRlZF8yYCAtIENvbnRyb2xfMikgJT4lIAogIHNlbGVjdCgtYyhgTWFsZS1saW1pdGVkXzFgLCBDb250cm9sXzEsIGBGZW1hbGUtbGltaXRlZF8xYCwKICAgICAgICAgICAgYE1hbGUtbGltaXRlZF8yYCwgQ29udHJvbF8yLCBgRmVtYWxlLWxpbWl0ZWRfMmApKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gIkNvbnRyYXN0IiwgdmFsdWVzX3RvID0gImdlbmVyYXRpb25fZGlmZiIpCmBgYAoKQ3JlYXRlIHBhbmVscyBiIGFuZCBjIG9mIEZpZ3VyZSAxCgpgYGB7cn0KIyBwbG90IHRoZSBtZWFucwoKIyBibG9jayAxCgpleHRfcDFfQjEgPC0gCiAgbWVhbl93ZWlidWxsX2VzdGltYXRlcyAlPiUgCiAgZmlsdGVyKEJsb2NrID09ICIxIikgJT4lIAogIGdncGxvdChhZXMoeCA9IGdlbmVyYXRpb25zLCB5ID0gYEV2b2x1dGlvbiB0cmVhdG1lbnRgKSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IGBFdm9sdXRpb24gdHJlYXRtZW50YCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBzbGFiX2NvbG91ciA9ICJibGFjayIsIHNsYWJfc2l6ZSA9IDAuOCkgKyAjIHdpZHRoIGluZGljYXRlcyB0aGUgdW5jZXJ0YWludHkgaW50ZXJ2YWxzOiBoZXJlIHdlIGhhdmUgNjYlIGFuZCA5NSUgaW50ZXJ2YWxzICsgIyB3aWR0aCBpbmRpY2F0ZXMgdGhlIHVuY2VydGFpbnR5IGludGVydmFsczogaGVyZSB3ZSBoYXZlIDY2JSBhbmQgOTUlIGludGVydmFscysKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGxhYnMoeCA9ICJNZWFuIGdlbmVyYXRpb25zIHRpbGwgZXh0aW5jdGlvbiIsIHkgPSAiU2VsZWN0aW9uIHJlc3BvbnNlIGhpc3RvcnkiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoNCwgMTIsIDEpKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvcj1OQSksICN0cmFuc3BhcmVudCBwbG90IGJnCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAjdHJhbnNwYXJlbnQgbGVnZW5kIHBhbmVsCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCiMgcGxvdCB0aGUgY29udHJhc3RzCgpleHRfcDJfQjEgPC0gCiAgd2VpYnVsbF9jb250cmFzdHNfQjEgJT4lIAogIGdncGxvdChhZXMoeCA9IGdlbmVyYXRpb25fZGlmZiwgeSA9IGZjdF9yZWxldmVsKENvbnRyYXN0LCAiRmVtYWxlIC0gQ29udHJvbCIsICJNYWxlIC0gRmVtYWxlIiwgIk1hbGUgLSBDb250cm9sIikpKSArCiAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gQ29udHJhc3QpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgc2xhYl9jb2xvdXIgPSAiYmxhY2siLCBzbGFiX3NpemUgPSAwLjgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhjYXJ0b19wYWwoNywgIlBlYWNoIilbMl0sIGNhcnRvX3BhbCg3LCAiUHVycCIpWzFdLCBjYXJ0b19wYWwoNywgIlRlYWxHcm4iKVsxXSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIkRpZmYuIGluIGdlbmVyYXRpb25zIHRpbGwgZXh0aW5jdGlvbiIsIHkgPSAiVHJlYXRtZW50IGNvbnRyYXN0IikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKC00LCA2LCAyKSkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvcj1OQSksICN0cmFuc3BhcmVudCBwbG90IGJnCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAjdHJhbnNwYXJlbnQgbGVnZW5kIHBhbmVsCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCmBgYAoKV2UgY2FuIGFsc28gZXN0aW1hdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBldm9sdXRpb25hcnkgdHJlYXRtZW50cyBpbiB0aGUgcHJvcG9ydGlvbiBvZiBsaW5lYWdlcyBleHRhbnQgaW4gZWFjaCBnZW5lcmF0aW9uLiBCZWxvdyB3ZSBjYWxjdWxhdGUgZWFjaCBjb250cmFzdCBhbmQgbWFrZSBwYW5lbHMgZCwgZSBhbmQgZgoKYGBge3J9CgojIEJsb2NrIDEKCkRpZmZlcmVuY2VfZ2Vuc19CMSA8LQogIFdlaWJ1bGxfc3Vydml2YWxfY3VydmUgJT4lIAogIHNlbGVjdChjb250YWlucygiQjEiKSkgJT4lIAogIG11dGF0ZShHMV9kaWZmLmMgPSBNYWxlXzFfQjEgLSBDb250cm9sXzFfQjEsCiAgICAgICAgIEcxX2RpZmYuZiA9IE1hbGVfMV9CMSAtIEZlbWFsZV8xX0IxLAogICAgICAgICBHMV9kaWZmLmZjID0gRmVtYWxlXzFfQjEgLSBDb250cm9sXzFfQjEsCiAgICAgICAgIEcyX2RpZmYuYyA9IE1hbGVfMl9CMSAtIENvbnRyb2xfMl9CMSwKICAgICAgICAgRzJfZGlmZi5mID0gTWFsZV8yX0IxIC0gRmVtYWxlXzJfQjEsCiAgICAgICAgIEcyX2RpZmYuZmMgPSBGZW1hbGVfMl9CMSAtIENvbnRyb2xfMl9CMSwKICAgICAgICAgRzNfZGlmZi5jID0gTWFsZV8zX0IxIC0gQ29udHJvbF8zX0IxLAogICAgICAgICBHM19kaWZmLmYgPSBNYWxlXzNfQjEgLSBGZW1hbGVfM19CMSwKICAgICAgICAgRzNfZGlmZi5mYyA9IEZlbWFsZV8zX0IxIC0gQ29udHJvbF8zX0IxLAogICAgICAgICBHNF9kaWZmLmMgPSBNYWxlXzRfQjEgLSBDb250cm9sXzRfQjEsCiAgICAgICAgIEc0X2RpZmYuZiA9IE1hbGVfNF9CMSAtIEZlbWFsZV80X0IxLAogICAgICAgICBHNF9kaWZmLmZjID0gRmVtYWxlXzRfQjEgLSBDb250cm9sXzRfQjEsCiAgICAgICAgIEc1X2RpZmYuYyA9IE1hbGVfNV9CMSAtIENvbnRyb2xfNV9CMSwKICAgICAgICAgRzVfZGlmZi5mID0gTWFsZV81X0IxIC0gRmVtYWxlXzVfQjEsCiAgICAgICAgIEc1X2RpZmYuZmMgPSBGZW1hbGVfNV9CMSAtIENvbnRyb2xfNV9CMSwKICAgICAgICAgRzZfZGlmZi5jID0gTWFsZV82X0IxIC0gQ29udHJvbF82X0IxLAogICAgICAgICBHNl9kaWZmLmYgPSBNYWxlXzZfQjEgLSBGZW1hbGVfNl9CMSwKICAgICAgICAgRzZfZGlmZi5mYyA9IEZlbWFsZV82X0IxIC0gQ29udHJvbF82X0IxLAogICAgICAgICBHN19kaWZmLmMgPSBNYWxlXzdfQjEgLSBDb250cm9sXzdfQjEsCiAgICAgICAgIEc3X2RpZmYuZiA9IE1hbGVfN19CMSAtIEZlbWFsZV83X0IxLAogICAgICAgICBHN19kaWZmLmZjID0gRmVtYWxlXzdfQjEgLSBDb250cm9sXzdfQjEsCiAgICAgICAgIEc4X2RpZmYuYyA9IE1hbGVfOF9CMSAtIENvbnRyb2xfOF9CMSwKICAgICAgICAgRzhfZGlmZi5mID0gTWFsZV84X0IxIC0gRmVtYWxlXzhfQjEsCiAgICAgICAgIEc4X2RpZmYuZmMgPSBGZW1hbGVfOF9CMSAtIENvbnRyb2xfOF9CMSwKICAgICAgICAgRzlfZGlmZi5jID0gTWFsZV85X0IxIC0gQ29udHJvbF85X0IxLAogICAgICAgICBHOV9kaWZmLmYgPSBNYWxlXzlfQjEgLSBGZW1hbGVfOV9CMSwKICAgICAgICAgRzlfZGlmZi5mYyA9IEZlbWFsZV85X0IxIC0gQ29udHJvbF85X0IxLAogICAgICAgICBHMTBfZGlmZi5jID0gTWFsZV8xMF9CMSAtIENvbnRyb2xfMTBfQjEsCiAgICAgICAgIEcxMF9kaWZmLmYgPSBNYWxlXzEwX0IxIC0gRmVtYWxlXzEwX0IxLAogICAgICAgICBHMTBfZGlmZi5mYyA9IEZlbWFsZV8xMF9CMSAtIENvbnRyb2xfMTBfQjEsCiAgICAgICAgIEcxMV9kaWZmLmMgPSBNYWxlXzExX0IxIC0gQ29udHJvbF8xMV9CMSwKICAgICAgICAgRzExX2RpZmYuZiA9IE1hbGVfMTFfQjEgLSBGZW1hbGVfMTFfQjEsCiAgICAgICAgIEcxMV9kaWZmLmZjID0gRmVtYWxlXzExX0IxIC0gQ29udHJvbF8xMV9CMSwKICAgICAgICAgRzEyX2RpZmYuYyA9IE1hbGVfMTJfQjEgLSBDb250cm9sXzEyX0IxLAogICAgICAgICBHMTJfZGlmZi5mID0gTWFsZV8xMl9CMSAtIEZlbWFsZV8xMl9CMSwKICAgICAgICAgRzEyX2RpZmYuZmMgPSBGZW1hbGVfMTJfQjEgLSBDb250cm9sXzEyX0IxLAogICAgICAgICBHMTNfZGlmZi5jID0gTWFsZV8xM19CMSAtIENvbnRyb2xfMTNfQjEsCiAgICAgICAgIEcxM19kaWZmLmYgPSBNYWxlXzEzX0IxIC0gRmVtYWxlXzEzX0IxLAogICAgICAgICBHMTNfZGlmZi5mYyA9IEZlbWFsZV8xM19CMSAtIENvbnRyb2xfMTNfQjEsCiAgICAgICAgIEcxNF9kaWZmLmMgPSBNYWxlXzE0X0IxIC0gQ29udHJvbF8xNF9CMSwKICAgICAgICAgRzE0X2RpZmYuZiA9IE1hbGVfMTRfQjEgLSBGZW1hbGVfMTRfQjEsCiAgICAgICAgIEcxNF9kaWZmLmZjID0gRmVtYWxlXzE0X0IxIC0gQ29udHJvbF8xNF9CMSwKICAgICAgICAgRzE1X2RpZmYuYyA9IE1hbGVfMTVfQjEgLSBDb250cm9sXzE1X0IxLAogICAgICAgICBHMTVfZGlmZi5mID0gTWFsZV8xNV9CMSAtIEZlbWFsZV8xNV9CMSwKICAgICAgICAgRzE1X2RpZmYuZmMgPSBGZW1hbGVfMTVfQjEgLSBDb250cm9sXzE1X0IxLAogICAgICAgICBHMTZfZGlmZi5jID0gTWFsZV8xNl9CMSAtIENvbnRyb2xfMTZfQjEsCiAgICAgICAgIEcxNl9kaWZmLmYgPSBNYWxlXzE2X0IxIC0gRmVtYWxlXzE2X0IxLAogICAgICAgICBHMTZfZGlmZi5mYyA9IEZlbWFsZV8xNl9CMSAtIENvbnRyb2xfMTZfQjEsCiAgICAgICAgIEcxN19kaWZmLmMgPSBNYWxlXzE3X0IxIC0gQ29udHJvbF8xN19CMSwKICAgICAgICAgRzE3X2RpZmYuZiA9IE1hbGVfMTdfQjEgLSBGZW1hbGVfMTdfQjEsCiAgICAgICAgIEcxN19kaWZmLmZjID0gRmVtYWxlXzE3X0IxIC0gQ29udHJvbF8xN19CMSwKICAgICAgICAgRzE4X2RpZmYuYyA9IE1hbGVfMThfQjEgLSBDb250cm9sXzE4X0IxLAogICAgICAgICBHMThfZGlmZi5mID0gTWFsZV8xOF9CMSAtIEZlbWFsZV8xOF9CMSwKICAgICAgICAgRzE4X2RpZmYuZmMgPSBGZW1hbGVfMThfQjEgLSBDb250cm9sXzE4X0IxLAogICAgICAgICBHMTlfZGlmZi5jID0gTWFsZV8xOV9CMSAtIENvbnRyb2xfMTlfQjEsCiAgICAgICAgIEcxOV9kaWZmLmYgPSBNYWxlXzE5X0IxIC0gRmVtYWxlXzE5X0IxLAogICAgICAgICBHMTlfZGlmZi5mYyA9IEZlbWFsZV8xOV9CMSAtIENvbnRyb2xfMTlfQjEsCiAgICAgICAgIEcyMF9kaWZmLmMgPSBNYWxlXzIwX0IxIC0gQ29udHJvbF8yMF9CMSwKICAgICAgICAgRzIwX2RpZmYuZiA9IE1hbGVfMjBfQjEgLSBGZW1hbGVfMjBfQjEsCiAgICAgICAgIEcyMF9kaWZmLmZjID0gRmVtYWxlXzIwX0IxIC0gQ29udHJvbF8yMF9CMSwKICAgICAgICAgRzIxX2RpZmYuYyA9IE1hbGVfMjFfQjEgLSBDb250cm9sXzIxX0IxLAogICAgICAgICBHMjFfZGlmZi5mID0gTWFsZV8yMV9CMSAtIEZlbWFsZV8yMV9CMSwKICAgICAgICAgRzIxX2RpZmYuZmMgPSBGZW1hbGVfMjFfQjEgLSBDb250cm9sXzIxX0IxLAogICAgICAgICBHMjJfZGlmZi5jID0gTWFsZV8yMl9CMSAtIENvbnRyb2xfMjJfQjEsCiAgICAgICAgIEcyMl9kaWZmLmYgPSBNYWxlXzIyX0IxIC0gRmVtYWxlXzIyX0IxLAogICAgICAgICBHMjJfZGlmZi5mYyA9IEZlbWFsZV8yMl9CMSAtIENvbnRyb2xfMjJfQjEsCiAgICAgICAgIEcyM19kaWZmLmMgPSBNYWxlXzIzX0IxIC0gQ29udHJvbF8yM19CMSwKICAgICAgICAgRzIzX2RpZmYuZiA9IE1hbGVfMjNfQjEgLSBGZW1hbGVfMjNfQjEsCiAgICAgICAgIEcyM19kaWZmLmZjID0gRmVtYWxlXzIzX0IxIC0gQ29udHJvbF8yM19CMSwKICAgICAgICAgRzI0X2RpZmYuYyA9IE1hbGVfMjRfQjEgLSBDb250cm9sXzI0X0IxLAogICAgICAgICBHMjRfZGlmZi5mID0gTWFsZV8yNF9CMSAtIEZlbWFsZV8yNF9CMSwKICAgICAgICAgRzI0X2RpZmYuZmMgPSBGZW1hbGVfMjRfQjEgLSBDb250cm9sXzI0X0IxLAogICAgICAgICBHMjVfZGlmZi5jID0gTWFsZV8yNV9CMSAtIENvbnRyb2xfMjVfQjEsCiAgICAgICAgIEcyNV9kaWZmLmYgPSBNYWxlXzI1X0IxIC0gRmVtYWxlXzI1X0IxLAogICAgICAgICBHMjVfZGlmZi5mYyA9IEZlbWFsZV8yNV9CMSAtIENvbnRyb2xfMjVfQjEsCiAgICAgICAgIEcyNl9kaWZmLmMgPSBNYWxlXzI2X0IxIC0gQ29udHJvbF8yNl9CMSwKICAgICAgICAgRzI2X2RpZmYuZiA9IE1hbGVfMjZfQjEgLSBGZW1hbGVfMjZfQjEsCiAgICAgICAgIEcyNl9kaWZmLmZjID0gRmVtYWxlXzI2X0IxIC0gQ29udHJvbF8yNl9CMSwKICAgICAgICAgRzI3X2RpZmYuYyA9IE1hbGVfMjdfQjEgLSBDb250cm9sXzI3X0IxLAogICAgICAgICBHMjdfZGlmZi5mID0gTWFsZV8yN19CMSAtIEZlbWFsZV8yN19CMSwKICAgICAgICAgRzI3X2RpZmYuZmMgPSBGZW1hbGVfMjdfQjEgLSBDb250cm9sXzI3X0IxLAogICAgICAgICBHMjhfZGlmZi5jID0gTWFsZV8yOF9CMSAtIENvbnRyb2xfMjhfQjEsCiAgICAgICAgIEcyOF9kaWZmLmYgPSBNYWxlXzI4X0IxIC0gRmVtYWxlXzI4X0IxLAogICAgICAgICBHMjhfZGlmZi5mYyA9IEZlbWFsZV8yOF9CMSAtIENvbnRyb2xfMjhfQjEsCiAgICAgICAgIEcyOV9kaWZmLmMgPSBNYWxlXzJfQjEgLSBDb250cm9sXzI5X0IxLAogICAgICAgICBHMjlfZGlmZi5mID0gTWFsZV8yOV9CMSAtIEZlbWFsZV8yOV9CMSwKICAgICAgICAgRzI5X2RpZmYuZmMgPSBGZW1hbGVfMjlfQjEgLSBDb250cm9sXzI5X0IxKSAlPiUgCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJHIikpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGV2ZXJ5dGhpbmcoKSwgbmFtZXNfdG8gPSAiRGlmZmVyZW5jZSBjb250cmFzdCIsIHZhbHVlc190byA9ICJzdXJ2aXZhbF9kaWZmIikgJT4lIAogIHNlcGFyYXRlKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCwgaW50byA9IGMoIkdlbmVyYXRpb24iLCAiRGlmZmVyZW5jZSBjb250cmFzdCIpLCBzZXAgPSAiXyIpICU+JSAKICBtdXRhdGUoR2VuZXJhdGlvbiA9IGFzLm51bWVyaWMoc3RyX3JlbW92ZShHZW5lcmF0aW9uLCAiRyIpKSkKCgojIE1ha2UgdGhlIHRocmVlIHBsb3RzCgpMZWFmX3Bsb3RfbWNfQjEgPC0KICBEaWZmZXJlbmNlX2dlbnNfQjEgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5jIikgJT4lIAogIGdncGxvdChhZXMoc3Vydml2YWxfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlB1cnAiKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIk1hbGUgLSBDb250cm9sXG5Qcm9wLiBzdXJ2IGxpbmVhZ2VzIiwKICAgICAgIHkgPSAiR2VuZXJhdGlvbiBvZiBpbmJyZWVkaW5nIikgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgCgpMZWFmX3Bsb3RfbWZfQjEgPC0KICBEaWZmZXJlbmNlX2dlbnNfQjEgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5mIikgJT4lIAogIGdncGxvdChhZXMoc3Vydml2YWxfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlRlYWxHcm4iKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIk1hbGUgLSBGZW1hbGVcblByb3AuIHN1cnYgbGluZWFnZXMiLAogICAgICAgeSA9IE5VTEwpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgpMZWFmX3Bsb3RfZmNfQjEgPC0KICBEaWZmZXJlbmNlX2dlbnNfQjEgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5mYyIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJQZWFjaCIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTAuMSwgMC4zKSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPXJldikgKwogIGdlb21fdmxpbmUobGluZXR5cGUgPSAyLCB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDEpICsKICBsYWJzKHggPSAiRmVtYWxlIC0gQ29udHJvbFxuUHJvcC4gc3VydiBsaW5lYWdlcyIsCiAgICAgICB5ID0gTlVMTCkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkKCmBgYAoKQ29tYmluZSB0aGUgNiBwYW5lbHMKCmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTB9Cih3ZWlidWxsX3N1cnZfcGxvdF9CMSAvIChleHRfcDFfQjEgKyBleHRfcDJfQjEpKSAvIChMZWFmX3Bsb3RfbWNfQjEgKyBMZWFmX3Bsb3RfbWZfQjEgKyBMZWFmX3Bsb3RfZmNfQjEpICsKICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICdhJykKYGBgCgoKKipGaWd1cmUgMSoqLiAuLi4gCgokfiQKCiMjIFByb2R1Y3Rpdml0eSBhbmFseXNpcwoKJH4kCgoKV2UgaGF2ZSBzZXZlcmFsIGh5cG90aGVzZXMgdGhhdCB3ZSB0ZXN0IHdpdGggdGhlIHByb2R1Y3Rpdml0eSBkYXRhLiBGaXJzdCwgcHJvZHVjdGl2aXR5IHNob3VsZCBiZSBuZWdhdGl2ZWx5IGNvcnJlbGF0ZWQgd2l0aCB0aGUgbnVtYmVyIG9mIGdlbmVyYXRpb25zIGluYnJlZWRpbmcgb2NjdXJzLCBkdWUgdG8gaW5icmVlZGluZyBkZXByZXNzaW9uLiBBcyBtZW50aW9uZWQgYWJvdmUsIHRoaXMgZWZmZWN0IHNob3VsZCBiZSBzdHJvbmdlc3QgaW4gdGhlIGZpcnN0IH4xMCBnZW5lcmF0aW9ucyBvZiB0aGUgZXhwZXJpbWVudCwgZHVyaW5nIHdoaWNoIGZ1bGwtc2libGluZyBpbmJyZWVkaW5nIHNob3VsZCBoYXZlIHRoZSBsYXJnZXN0IGVmZmVjdHMgb24gZ2Vub21lIHdpZGUgaGV0ZXJvenlnb3NpdHkuIEFmdGVyIHRoaXMgcG9pbnQsIHRoZSBpbmJyZWVkaW5nIGNvZWZmaWNpZW50IHdpbGwgYmUgMC44OSwgd2hpbGUgb3ZlciB0aGUgbmV4dCAxMCBnZW5lcmF0aW9ucyBpdCBzaG91bGQgb25seSBpbmNyZWFzZSBieSBhIGZ1cnRoZXIgMC4xIHRvIDAuOTkuIEhlbmNlLCB3ZSBleHBlY3QgcHJvZHVjdGl2aXR5IHRvIHN0YWJpbGlzZSBiZXR3ZWVuIHRoZSAxMHRoIGFuZCAyMHRoIGdlbmVyYXRpb25zLCBhc3N1bWluZyB0aGUgbGluZWFnZSBpcyBzdGlsbCBleHRhbnQuIFNlY29uZCwgbGluZWFnZXMgY2FycnlpbmcgYXV0b3NvbWVzIHRoYXQgaGF2ZSByZXNwb25kZWQgdG8gc2VsZWN0aW9uIG9uIG1hbGVzIHNob3VsZCBleGhpYml0IGEgc21hbGxlciBkcm9wIGluIHByb2R1Y3Rpdml0eSBjb21wYXJlZCB3aXRoIGxpbmVhZ2VzIGNhcnlyaW5nIHRoZSBmZW1hbGUtYWRhcHRlZCBvciBjb250cm9sIGF1dG9zb21lcywgYmVjYXVzZSB0aGV5IGhhdmUgYSBoaXN0b3J5IG9mIHN0cm9uZ2VyIHNlbGVjdGlvbiB0aGF0IHNob3VsZCwgaW4gdGhlb3J5LCBoYXZlIHB1cmdlZCB0aGUgZ2Vub21lIG9mIHJlY2Vzc2l2ZSBkZWxldGVyaW91cyBhbGxlbGVzLgoKIyMjIExvYWQgaW4gdGhlIGRhdGEKCmBgYHtyfQoKZGF0YSA8LQogIHJlYWRfY3N2KCJEYXRhL1Byb2R1Y3Rpdml0eV9kYXRhLmNzdiIpCgpQcm9kdWN0aXZpdHlfZGF0YSA8LSAKICBsZWZ0X2pvaW4oCiAgICBkYXRhLAogICAgCiAgICBkYXRhICU+JSAKICAgICAgZGlzdGluY3QoQ3Jvc3MsIFJlcGxpY2F0ZSkgJT4lIAogICAgICByb3dpZF90b19jb2x1bW4oIkxpbmVhZ2UiKQogICkgJT4lIAogIHNlbGVjdChMaW5lYWdlLCBldmVyeXRoaW5nKCkpICU+JSAKICBtdXRhdGUoYWNyb3NzKDE6NywgYXMuZmFjdG9yKSwKICAgICAgICAgQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nID0gRmVtYWxlX29mZnNwcmluZyArIE1hbGVfb2Zmc3ByaW5nLAogICAgICAgICBQcmVfd2luZG93X29mZnNwcmluZyA9IFByZV93aW5kb3dfZmVtYWxlX29mZnNwcmluZyArIFByZV93aW5kb3dfbWFsZV9vZmZzcHJpbmcsCiAgICAgICAgIFRvdGFsX2ZlbWFsZV9vZmZzcHJpbmcgPSBGZW1hbGVfb2Zmc3ByaW5nICsgUHJlX3dpbmRvd19mZW1hbGVfb2Zmc3ByaW5nLAogICAgICAgICBUb3RhbF9tYWxlX29mZnNwcmluZyA9IE1hbGVfb2Zmc3ByaW5nICsgUHJlX3dpbmRvd19tYWxlX29mZnNwcmluZywKICAgICAgICAgVG90YWxfb2Zmc3ByaW5nID0gVG90YWxfZmVtYWxlX29mZnNwcmluZyArIFRvdGFsX21hbGVfb2Zmc3ByaW5nKSAlPiUgCiAgIyBJbiBvbmUgZ2VuZXJhdGlvbiBvZiB0aGUgZXhwZXJpbWVudCAoYjEgPSBHMjQgJiBCMiA9IEcxNSkgc2libGluZyBwYWlycyB3ZXJlIHNldHVwIGEgZGF5IGVhcmx5IGFuZCByZW1vdmVkIGZyb20gdGhlaXIgdmlhbHMgYXQgdGhlIHJlZ3VsYXIgdGltZSwgbWVhbmluZyB0aGF0IHRoZXkgaGFkIGFuIGV4dHJhIGRheSB0byBwcm9kdWNlIG9mZnNwcmluZy4gVG8gY29ycmVjdCBmb3IgdGhpcyB3ZSBtdWx0aXBseSBvZmZzcHJpbmcgY291bnRzIGJ5IDAuNzUuCiAgbXV0YXRlKENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZyA9IGlmX2Vsc2UoQ291bnRfY29uZGl0aW9ucyA9PSAiRXh0cmEgZGF5IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nICogMC43NSksICBDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcpLAogICAgICAgICAjIG5vdGUgdGhhdCBiZWNhdXNlIGV2ZXJ5dGhpbmcgaXMgbW92ZWQgYSBkYXkgZWFybHksIHByZS13aW5kb3cgb2Zmc3ByaW5nIGNvdW50cyB3aWxsIHN0aWxsIGJlIGluZmxhdGVkIGV2ZW4gYWZ0ZXIgdGhpcyBjb3JyZWN0aW9uCiAgICAgICAgIFByZV93aW5kb3dfb2Zmc3ByaW5nID0gaWZfZWxzZShDb3VudF9jb25kaXRpb25zID09ICJFeHRyYSBkYXkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChQcmVfd2luZG93X29mZnNwcmluZyAqIDAuNzUpLCAgUHJlX3dpbmRvd19vZmZzcHJpbmcpKQogIAojIE1ha2UgYSB0aWJibGUgdGhhdCBvbmx5IGluY2x1ZGVzIGRhdGEgZnJvbSB0aGUgZmlyc3QgMjAgZ2VuZXJhdGlvbnMgb2YgdGhlIGV4cGVyaW1lbnQgKEJsb2NrIDEgcmFuIGZvciAyOSBnZW5zLCB3aGlsZSBCbG9jayAyIHJhbiBmb3IgMjApLiBUaGVuIHJlbW92ZSBsaW5lYWdlJ3MgdGhhdCBhdCBzb21lIHBvaW50IHdlcmUgbG9zdCBiZWNhdXNlIG9mIGhhbmRsaW5nIGVycm9ycyBhbmQgdGh1cyBkbyBub3QgaGF2ZSBkYXRhIGZyb20gdGhhdCBnZW5lcmF0aW9uIG9ud2FyZHMuCgpQcm9kdWN0aXZpdHlfZGF0YV9jbGVhbiA8LQogIGxlZnRfam9pbigKICAgIFByb2R1Y3Rpdml0eV9kYXRhICU+JSAKICAgICAgZmlsdGVyKEdlbmVyYXRpb24gPCAyMSkgJT4lIAogICAgICBmaWx0ZXIoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nICE9ICJOQSIpICU+JSAjIHJlbW92ZSBOQSB2YWx1ZXMKICAgICAgZ3JvdXBfYnkoTGluZWFnZSwgQmxvY2spICU+JSAjIHRoZXNlIHJlbWFpbmluZyBsaW5lcyByZW1vdmUgbGluZWFnZSdzIHRoYXQgaGFkIGFuIE5BIHZhbHVlIAogICAgICBjb3VudCgpICU+JSAKICAgICAgdW5ncm91cCgpICU+JSAKICAgICAgZmlsdGVyKG4gPT0gMjApLCAjIHJlbW92ZSBsaW5lYWdlJ3MgdGhhdCBoYXZlIE5BIHZhbHVlcyBmb3IgcHJvZHVjdGl2aXR5IGluIGF0IGxlYXN0IG9uZSBnZW5lcmF0aW9uCiAgICAKICAgIFByb2R1Y3Rpdml0eV9kYXRhKSAlPiUgCiAgZmlsdGVyKEdlbmVyYXRpb24gPCAyMSkgIyBvbmx5IGluY2x1ZGUgZGF0YSBjb2xsZWN0ZWQgb24gdGhlIGZpcnN0IDIwIGdlbmVyYXRpb25zIG9mIGluYnJlZWRpbmcgKGJsb2NrIDIncyBlbmRwb2ludCkKCiMgV2UgYWxzbyBpbmNsdWRlIGEgY29sdW1uIHRoYXQgc3BlY2lmaWVzIGlmIGEgbGluZWFnZSB3YXMgZXh0aW5jdC4gVGhpcyBtZWFucyB3ZSBjYW4gZWFzaWx5IHJlbW92ZSAwIHZhbHVlcyBmcm9tIHRoZSBkYXRhIGlmIHJlcXVpcmVkLiBXZSBjYW4gdXNlIHRoZSBgZXh0aW5jdGlvbl9kYXRhX3dyYW5nbGVkJEdlbnNfdG9fZXh0aW5jdGAgY29sdW1uIHRvIGhlbHAgdXMgaGVyZS4gCgpQcm9kdWN0aXZpdHlfZGF0YV9jbGVhbl8yIDwtCiAgbGVmdF9qb2luKAogICAgUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW4sICAKICAgIGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCAlPiUgCiAgICAgIHNlbGVjdChMaW5lYWdlLCBHZW5zX3RvX2V4dGluY3QpCiAgKSAlPiUgCiAgbXV0YXRlKEV4dGluY3QgPSBpZl9lbHNlKEdlbmVyYXRpb24gPiBHZW5zX3RvX2V4dGluY3QsICJZZXMiLCAiTm8iKSkKCiMgQ3JlYXRlIGEgZnVuY3Rpb24gdG8gYnVpbGQgSFRNTCBzZWFyY2hhYmxlIHRhYmxlcwoKbXlfZGF0YV90YWJsZSA8LSBmdW5jdGlvbihkZil7CiAgZGF0YXRhYmxlKAogICAgZGYsIHJvd25hbWVzPUZBTFNFLAogICAgYXV0b0hpZGVOYXZpZ2F0aW9uID0gVFJVRSwKICAgIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICAiQnV0dG9ucyIpLAogICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICBkZWZlclJlbmRlcj1UUlVFLAogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLAogICAgICBzY3JvbGxDb2xsYXBzZT1UUlVFLAogICAgICBidXR0b25zID0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KAogICAgICAgICAgZXh0ZW5kID0gJ3BkZicsCiAgICAgICAgICBwYWdlU2l6ZSA9ICdBNCcsCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLAogICAgICAgICAgZmlsZW5hbWUgPSAnUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW5fMicpKSwKICAgICAgcGFnZUxlbmd0aCA9IDg1MDAKICAgICkKICApCn0KCm15X2RhdGFfdGFibGUoUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW5fMiAlPiUgCiAgICAgICAgICAgICAgICBzZWxlY3QoTW90aGVyX3N0cmFpbiwgRmF0aGVyX3N0cmFpbiwgQ3Jvc3MsIExpbmVhZ2UsIEJsb2NrLCBHZW5lcmF0aW9uLCBUcmVhdG1lbnQsIEV4dGluY3QsIENvdW50X2NvbmRpdGlvbnMsIEZlbWFsZV9vZmZzcHJpbmcsIE1hbGVfb2Zmc3ByaW5nLCBDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcsIFByZV93aW5kb3dfZmVtYWxlX29mZnNwcmluZywgUHJlX3dpbmRvd19tYWxlX29mZnNwcmluZywgUHJlX3dpbmRvd19vZmZzcHJpbmcsIFRvdGFsX2ZlbWFsZV9vZmZzcHJpbmcsIFRvdGFsX21hbGVfb2Zmc3ByaW5nLCBUb3RhbF9vZmZzcHJpbmcpKQoKYGBgCgoqKkNvbHVtbiBleHBsYW5hdGlvbnMqKgoKYE1vdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgYEV2b2x1dGlvbl90cmVhdG1lbnRgLiBUaGlzIGNvbHVtbiBzaG93cyB0aGUgc3RyYWluIHRoYXQgdGhlIGZvdW5kaW5nIGZlbWFsZSBvZiB0aGUgbGluZWFnZSB3YXMgZGVyaXZlZCBmcm9tLgoKYEZhdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgZXZvbHV0aW9uIHRyZWF0bWVudC4gVGhpcyBjb2x1bW4gc2hvd3MgdGhlIHN0cmFpbiB0aGF0IHRoZSBmb3VuZGluZyBtYWxlIG9mIHRoZSBsaW5lYWdlIHdhcyBkZXJpdmVkIGZyb20uCgpgQ3Jvc3NgOiBhbiBpZGVudGlmeWluZyBJRCBmb3IgZWFjaCBvZiB0aGUgMzYgY29tYmluYXRpb25zIG9mIGBNb3RoZXIgc3RyYWluYCBhbmQgYEZhdGhlciBzdHJhaW5gLiAKCmBMaW5lYWdlYDogbGluZXMgb2YgZmxpZXMgZm91bmRlZCBieSBzaW5nbGUgaW5zZW1pbmF0ZWQgZmVtYWxlcyBpbiBnZW5lcmF0aW9uIHplcm8uIFdlIGdlbmVyYXRlZCB0aGUgbmV4dCBnZW5lcmF0aW9uIG9mIGVhY2ggbGluZWFnZSBieSBjcm9zc2luZyBhIHNpbmdsZSBmdWxsLXNpYmxpbmcgZHlhZC4KCmBCbG9ja2A6IHRoZSBleHBlcmltZW50IHdhcyBydW4gaW4gMiBkaXN0aW5jdCBibG9ja3MsIHVzaW5nIGZsaWVzIHNlcGFyYXRlZCBieSA5IGdlbmVyYXRpb25zLiBCbG9jayAxIHJhbiBmb3IgMjkgZ2VuZXJhdGlvbnMsIHdoZXJlYXMgQmxvY2sgMiByYW4gZm9yIDIwIGdlbmVyYXRpb25zLgoKYEdlbmVyYXRpb25gOiB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgZXh0aW5jdGlvbiBhc3NheSwgcmFuZ2luZyBmcm9tIDEgdG8gMjAuIAoKYEV2b2x1dGlvbl90cmVhdG1lbnRgOiB0aGUgc3RyYWlucyBoYWQgYmVlbiBleHBvc2VkIHRvIG9uZSBvZiB0aHJlZSBldm9sdXRpb25hcnkgY29uZGl0aW9ucyBmb3IgMjAtMjkgZ2VuZXJhdGlvbnM6IGEgZmVtYWxlLWxpbWl0ZWQgcmVzcG9uc2UgdG8gc2VsZWN0aW9uLCBhIG1hbGUtbGltaXRlZCByZXNwb25zZSBhbmQgYSBjb250cm9sIGNvbmRpdGlvbiB3aGVyZSBhbiBldm9sdXRpb25hcnkgcmVzcG9uc2Ugb2NjdXJyZWQgaW4gYm90aCBzZXhlcy4KCmBFeHRpbmN0YDogc3BlY2lmaWVzIHdoZXRoZXIgdGhlIGxpbmVhZ2Ugd2FzIGV4dGluY3QgaW4gdGhpcyBnZW5lcmF0aW9uLgoKYENvdW50X2NvbmRpdGlvbnNgOiBOb3JtYWwgaW5kaWNhdGVzIHRoYXQgdGhlIGJyZWVkaW5nIHdpbmRvdyBsYXN0ZWQgdGhlIHN0YW5kYXJkIHRocmVlIGRheXMuIEV4dHJhIGRheSBpbmRpY2F0ZXMgdGhlIGJyZWVkaW5nIHBhaXIgd2VyZSBsZWZ0IGluIHRoZSB2aWFsIGZvciBhbiBleHRyYSBkYXkuIFRoaXMgb2NjdXJyZWQgZHVyaW5nIGdlbmVyYXRpb24gMTUgb2YgdGhlIHNlY29uZCBleHBlcmltZW50YWwgYmxvY2suCgpgRmVtYWxlX29mZnNwcmluZ2A6IHRoZSBudW1iZXIgb2YgYWR1bHQgZmVtYWxlcyBwcm9kdWNlZCBieSB0aGUgYnJlZWRpbmcgcGFpciB0aGF0IGVjbG9zZWQgZHVyaW5nIHRoZSBmb3VyLWRheSBjb2xsZWN0aW9uIHdpbmRvdwoKYE1hbGVfb2Zmc3ByaW5nYDogYXMgYWJvdmUsIGJ1dCBmb3IgbWFsZSBvZmZzcHJpbmcuCgpgQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nYDogdGhlIHN1bSBvZiBgRmVtYWxlX29mZnNwcmluZ2AgYW5kIGBNYWxlX29mZnNwcmluZ2AuCgpgUHJlX3dpbmRvd19mZW1hbGVfb2Zmc3ByaW5nYDogZmVtYWxlcyBwcm9nZW55IHRoYXQgZWNsb3NlZCBwcmlvciB0byB0aGUgY29sbGVjdGlvbiB3aW5kb3cgb3BlbmluZy4KCmBQcmVfd2luZG93X21hbGVfb2Zmc3ByaW5nYDogYXMgYWJvdmUsIGJ1dCBmb3IgbWFsZSBvZmZzcHJpbmcuCgpgUHJlX3dpbmRvd19vZmZzcHJpbmdgOiB0aGUgc3VtIG9mIGBQcmVfd2luZG93X2ZlbWFsZV9vZmZzcHJpbmdgIGFuZCBgUHJlX3dpbmRvd19tYWxlX29mZnNwcmluZ2AuCgpgVG90YWxfZmVtYWxlX29mZnNwcmluZ2A6IHRoZSBzdW0gb2YgYEZlbWFsZV9vZmZzcHJpbmdgIGFuZCBgUHJlX3dpbmRvd19mZW1hbGVfb2Zmc3ByaW5nYC4KCmBUb3RhbF9tYWxlX29mZnNwcmluZ2A6IGFzIGFib3ZlLCBidXQgZm9yIG1hbGUgb2Zmc3ByaW5nLgoKYFRvdGFsX29mZnNwcmluZ2A6IHRoZSB0b3RhbCBudW1iZXIgb2Ygb2Zmc3ByaW5nIHByb2R1Y2VkLCBzdW1tZWQgYWNyb3NzIHRoZSBzZXhlcyBhbmQgdGhlIHByZS13aW5kb3cgYW5kIHdpdGhpbi13aW5kb3cgY29sbGVjdGlvbnMuCgokfiQKCiMjIyBEbyB3ZSBvYnNlcnZlIGluYnJlZWRpbmcgZGVwcmVzc2lvbj8KCiR+JAoKTGV0J3MgcGxvdCB0aGUgcmF3IGRhdGEgdG8gZ2V0IGFuIGlkZWEuCgpgYGB7cn0KCiMgQ29sbGVjdGlvbiB3aW5kb3cgcGxvdAoKcG9pbnRfcGxvdF8xIDwtCiAgUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW4gJT4lCiAgZ2dwbG90KGFlcyh4ID0gR2VuZXJhdGlvbiwgeSA9IENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZykpICsKICBnZW9tX2ppdHRlcihjb2xvdXIgPSBtZXQuYnJld2VyKCJPS2VlZmZlMiIpWzJdLCB3aWR0aCA9IDAuMjUsIAogICAgICAgICAgICAgIHNoYXBlID0gMS41LCBzdHJva2UgPTIsIHNpemUgPSAxLjIsIGFscGhhID0gMC4yNSkgKwogIGdlb21fc21vb3RoKHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbN10pICsKICBnZW9tX3Ntb290aChkYXRhID0gUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW5fMiAlPiUgZmlsdGVyKEV4dGluY3QgPT0gIk5vIiksIHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbNl0pICsKICB0aGVtZV90aWR5YmF5ZXMoKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDEsIDIwKSkgKwogIGxhYnMoeSA9ICJDb2xsZWN0aW9uIHdpbmRvd1xub2Zmc3ByaW5nIHByb2R1Y3Rpb24iLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpCgojIFRvdGFsIHByb2R1Y3Rpdml0eSBwbG90Cgpwb2ludF9wbG90XzIgPC0KICBQcm9kdWN0aXZpdHlfZGF0YSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gR2VuZXJhdGlvbiwgeSA9IFRvdGFsX29mZnNwcmluZykpICsKICBnZW9tX2ppdHRlcihjb2xvdXIgPSBtZXQuYnJld2VyKCJPS2VlZmZlMiIpWzJdLCB3aWR0aCA9IDAuMjUsIAogICAgICAgICAgICAgIHNoYXBlID0gMS41LCBzdHJva2UgPTIsIHNpemUgPSAxLjIsIGFscGhhID0gMC4yNSkgKwogIGdlb21fc21vb3RoKHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbN10pICsKICBnZW9tX3Ntb290aChkYXRhID0gUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW5fMiAlPiUgZmlsdGVyKEV4dGluY3QgPT0gIk5vIiksIHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbNl0pICsKICB0aGVtZV90aWR5YmF5ZXMoKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDEsIDIwKSkgKwogIGxhYnMoeSA9ICJUb3RhbCBvZmZzcHJpbmcgcHJvZHVjdGlvbiIsIHggPSAiR2VuZXJhdGlvbiBvZiBpbmJyZWVkaW5nIikgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkKCnBvaW50X3Bsb3RfMSAvIHBvaW50X3Bsb3RfMgoKYGBgCgokfiQKCiMjIyBUZXN0aW5nIGZvciBvdXIgY2FzdWFsIGVmZmVjdAoKJH4kCgojIyMjIE1vZGVsbGluZyBhcHByb2FjaAoKQXMgbWVudGlvbmVkIGFib3ZlLCB3ZSBoYXZlIHN0cm9uZyBleHBlY3RhdGlvbnMgZm9yIGhvdyBmdWxsLXNpYmxpbmcgaW5icmVlZGluZyBzaG91bGQgYWZmZWN0IHByb2R1Y3Rpdml0eS4gRGVjcmVhc2luZyBnZW5vbWUtd2lkZSBoZXRlcm96eWdvc2l0eSBhbmQgdGhlIGV4cHJlc3Npb24gb2YgcmVjZXNzaXZlIGRlbGV0ZXJpb3VzIGFsbGVsZXMgdGhhdCBjb21lcyB3aXRoIHRoaXMgc2hvdWxkIGZvbGxvdyBhIHBhdHRlcm4gb2YgZXhwb25lbnRpYWwgZGVjYXkuIFRoaXMgbm9uLWxpbmVhciBwcm9jZXNzIGNhbiBiZSBtb2RlbGxlZCB1c2luZyB0aGUgYGJybXNgIG5vbi1saW5lYXIgc3ludGF4LiAKCkhlcmUgd2UgbW9kZWwgdGhlIHByb2R1Y3Rpdml0eSBhdCBnZW5lcmF0aW9uICR0JCB2aWEgdGhlIGZ1bmN0aW9uICRhIC0gZV57XGxhbWJkYSB0fSQgd2hlcmUgJGEkIGFuZCAkXGxhbWJkYSQgYXJlIHBhcmFtZXRlcnMgdGhhdCBjb250cm9sIHRoZSBpbml0aWFsIHByb2R1Y3Rpdml0eSBhbmQgdGhlIHJhdGUgb2YgaXRzIGRlY2F5IGFzIGdlbmVyYXRpb25zIG9mIGluYnJlZWRpbmcgcHJvZ3Jlc3MuIFdlIGZvcmNlICRhJCB0byBiZSBwb3NpdGl2ZSB1c2luZyB0aGUgYGV4cCgpYCBmdW5jdGlvbiwgd2hpY2ggZXhwcmVzc2VzIGl0IG9uIHRoZSBleHBvbmVudGlhbCBzY2FsZS4gTGFyZ2UgJGEkIGluZGljYXRlcyBoaWdoZXIgc3RhcnRpbmcgcHJvZHVjdGl2aXR5IGF0IGdlbmVyYXRpb24gMCAod2Ugc3RhcnRlZCBvYnNlcnZhdGlvbiBhdCBnZW5lcmF0aW9uIDEsIHRoZSBwcm9kdWN0aXZpdHkgZm9yIHdoaWNoIGlzIGdpdmVuIGJ5ICRhIC0gZV57XGxhbWJkYX0kKS4gUG9zaXRpdmUgdmFsdWVzIG9mICRcbGFtYmRhJCBpbmRpY2F0ZSB0aGF0IHByb2R1Y3Rpdml0eSBkZWNsaW5lcyB3aXRoIGluYnJlZWRpbmcsIHdoaWNoIGlzIG91ciBzdHJvbmcgZXhwZWN0YXRpb24gYW5kIGNsZWFybHkgdGhlIGNhc2UgZm9sbG93aW5nIGluc3BlY3Rpb24gb2YgdGhlIHJhdyBkYXRhIChzZWUgRmlndXJlIFNYKS4gCgpXZSBtb2RlbCBpbmJyZWVkaW5nIGRlcHJlc3Npb24gd2hpbGUgaW5jbHVkaW5nIHplcm8gdmFsdWVzIGZvciBhbGwgcm93cyB3aGVyZSBhIGxpbmVhZ2Ugd2FzIGV4dGluY3QuIFRoaXMgaGVscHMgY29tYmF0IHVuZGVyZXN0aW1hdGlvbiBvZiB0aGUgZGVjYXkgcGFyYW1ldGVyLCBjYXVzZWQgYnkgdGhlIG5vbi1yYW5kb20gZXh0aW5jdGlvbiBvZiBsaW5lYWdlcywgd2hlcmUgaGlnaCBmaXRuZXNzIGxpbmVhZ2VzIGJlY29tZSBvdmVyLXJlcHJlc2VudGVkIGFzIHRoZSBnZW5lcmF0aW9ucyBvZiBpbmJyZWVkaW5nIHByb2dyZXNzIChpLmUuIHNlbGVjdGlvbikuIAoKKipGaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMqKgoKSW4gdGhlIGBicm1zYCBub24tbGluZWFyIHN5bnRheCwgZGlmZmVyZW50IGZvcm11bGFzIGNhbiBiZSBmaXQgZm9yIGVhY2ggcGFyYW1ldGVyLiBXZSBmaXQgdGhlIHNhbWUgZml4ZWQgZWZmZWN0cyBmb3IgJGEkIGFuZCAkXGxhbWJkYSQ6IGBFdm9sdXRpb24gdHJlYXRtZW50YCBhbmQgIGBCbG9ja2AuIFdlIGZpdCAnTGluZWFnZScgYXMgYSByYW5kb20gZWZmZWN0IHRvIGFjY291bnQgZm9yIHJlcGVhdGVkIG1lYXN1cmVtZW50cyB0YWtlbiBvbiBlYWNoIGxpbmVhZ2UgZm9yICRhJCwgYnV0IGFyZSB1bmFibGUgdG8gZG8gdGhpcyBmb3IgJFxsYW1iZGEkLCBhcyBpbmRpdmlkdWFsIGxpbmVhZ2UgcHJvZHVjdGl2aXR5IGN1cnZlcyBhcmUgaGlnaGx5IGhldGVyb3NrZWRhc3RpYywgYW5kIGFyZSBza2V3ZWQgYnkgZXh0aW5jdGlvbiBldmVudHMuIFRvIG1pbmltaXNlIHBzZXVkb3JlcGxpY2F0aW9uIGZvciAkXGxhbWJkYSQsIHdlIGZpdCBgQ3Jvc3NgIGFzIGEgcmFuZG9tIGVmZmVjdCAoY3VycmVudGx5IG9ubHkgb24gJFxsYW1iZGEkKSwgYXMgd2UgZG8gZm9yIHRoZSBleHRpbmN0aW9uIGRhdGEuCgokfiQKCiMjIyMgU2ltdWxhdGUgdGhlIGN1cnZlLCB3aXRoIHRoZSBwcmlvcnMgd2Ugd2lsbCBzcGVjaWZ5CgpgYGB7cn0KCm4gPC0gMWU0CgojIGRlZmluZSB0aGUgeC1heGlzIGJyZWFrcwphdCA8LSAxOjIwCgojIGhvdyBtYW55IHByaW9yIGRyYXdzIHdvdWxkIHlvdSBsaWtlPwpuX2RyYXdzIDwtIDIwMAoKIyBzaW11bGF0ZQpzZXQuc2VlZCgxNikKCnByaW9yIDwtCiAgdGliYmxlKGluZGV4ID0gMTpuLAogICAgICAgICBhICAgPSBybm9ybShuLCBtZWFuID0gNC41LCBzZCA9IDAuNSksCiAgICAgICAgIGxhbWJkYSAgICAgPSBybm9ybShuLCBtZWFuID0gMC4yLCBzZCA9IDAuMSkpICU+JSAKICBzbGljZV9zYW1wbGUobiA9IG5fZHJhd3MpICU+JSAKICBleHBhbmQobmVzdGluZyhpbmRleCwgYSwgbGFtYmRhKSwKICAgICAgICAgR2VuZXJhdGlvbiA9IHNlcShmcm9tID0gMCwgdG8gPSAyMCwgbGVuZ3RoLm91dCA9IDFlMikpICU+JSAKICBtdXRhdGUocHJvZHVjdGl2aXR5ID0gZXhwKGEgLSBsYW1iZGEgKiBHZW5lcmF0aW9uKSkgCgoKcHJpb3IgJT4lIAogIGdncGxvdChhZXMoeCA9IEdlbmVyYXRpb24sIHkgPSBwcm9kdWN0aXZpdHksIGdyb3VwID0gaW5kZXgpKSArCiAgZ2VvbV9saW5lKHNpemUgPSAxLzIsIGFscGhhID0gMS80LCBjb2xvdXIgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiKVsyXSkgKwogIHRoZW1lX3RpZHliYXllcygpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDMwMCksIGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLCAuMSkpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwyMCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBsYWJzKHkgPSAiTGluZWFnZSBwcm9kdWN0aXZpdHkiLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpCgpgYGAKCioqRmlndXJlIFhYKio6IFByaW9yIHByZWRpY3RpdmUgc2ltdWxhdGlvbiBmb3IgdGhlIHByb2R1Y3Rpdml0eSBkZWNsaW5lIG1vZGVsLiBUaGUgcGxvdCBzaG93cyB0aGUgcmVzdWx0cyBmcm9tIDEwMCBwcmlvciBkcmF3cy4KCiMjIyMgRml0IHRoZSBub24tbGluZWFyIG1vZGVsCgpgYGB7cn0KCm5vbmxpbmVhcl9wcm9kdWN0aXZpdHkgPC0gCiAgYnJtKGJmKENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZyB+IGV4cChhIC0gKGxhbWJkYSAqIEdlbmVyYXRpb24pKSwKICAgICAgICAgYSB+IDAgKyBUcmVhdG1lbnQgKiBCbG9jayArICgxfExpbmVhZ2UpLCAKICAgICAgICAgbGFtYmRhIH4gMCArIFRyZWF0bWVudCAqIEJsb2NrICsgKDF8Q3Jvc3MpLCAKICAgICAgICAgbmwgPSBUUlVFKSwKICAgICAgZGF0YSA9IFByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuLAogICAgICBmYW1pbHkgPSBuZWdiaW5vbWlhbChsaW5rID0gImlkZW50aXR5IiksCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoNC41LCAwLjUpLCBjbGFzcyA9IGIsIGNvZWYgPSBUcmVhdG1lbnRDb250cm9sLCBubHBhciA9ICJhIiksCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoNC41LCAwLjUpLCBjbGFzcyA9IGIsIGNvZWYgPSBUcmVhdG1lbnRGZW1hbGUsIG5scGFyID0gImEiKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCg0LjUsIDAuNSksIGNsYXNzID0gYiwgY29lZiA9IFRyZWF0bWVudE1hbGUsIG5scGFyID0gImEiKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAwLjUpLCBjbGFzcyA9IGIsIGNvZWYgPSBCbG9jazIsIG5scGFyID0gImEiKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLjIsIDAuMSksIGNsYXNzID0gYiwgY29lZiA9IFRyZWF0bWVudENvbnRyb2wsIG5scGFyID0gImxhbWJkYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAuMiwgMC4xKSwgY2xhc3MgPSBiLCBjb2VmID0gVHJlYXRtZW50RmVtYWxlLCBubHBhciA9ICJsYW1iZGEiKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLjIsIDAuMSksIGNsYXNzID0gYiwgY29lZiA9IFRyZWF0bWVudE1hbGUsIG5scGFyID0gImxhbWJkYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDAuMSksIGNsYXNzID0gYiwgY29lZiA9IEJsb2NrMiwgbmxwYXIgPSAibGFtYmRhIiksCiAgICAgICAgICAgICAgICBwcmlvcihnYW1tYSgzLCAxLjUpLCBjbGFzcyA9IHNkLCBubHBhciA9ICJhIiksCiAgICAgICAgICAgICAgICBwcmlvcihnYW1tYSgwLjEsIDIpLCBjbGFzcyA9IHNkLCBubHBhciA9ICJsYW1iZGEiKSksCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC44LCBtYXhfdHJlZWRlcHRoID0gMTUpLCBzZWVkID0gMSwKICAgICAgaXRlciA9IDMwMDAwLCB3YXJtdXAgPSA1MDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsCiAgICAgIGZpbGUgPSAiRml0cy9ub25fbGluZWFyX3Byb2R1Y3Rpdml0eV9tb2RlbF8yIikKCgpgYGAKCiMjIyMgSG93IGRvZXMgb3VyIGN1cnZlIGZpdCB0aGUgZGF0YQoKYGBge3J9CgoKbmV3X2RhdGEgPC0gCiAgUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW4gJT4lIAogIHNlbGVjdChHZW5lcmF0aW9uLCBUcmVhdG1lbnQsIEJsb2NrKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIG11dGF0ZShrZXkgPSBwYXN0ZSgiViIsIDE6bigpLCBzZXAgPSAiIikpCgpwcmVkcyA8LSBhcy5kYXRhLmZyYW1lKGZpdHRlZChub25saW5lYXJfcHJvZHVjdGl2aXR5LCBuZXdkYXRhID0gbmV3X2RhdGEsIHJlX2Zvcm11bGEgPSBOQSwgc3VtbWFyeT1GKSkgJT4lIAogIG11dGF0ZShkcmF3ID0gMTpuKCkpICU+JSAKICBnYXRoZXIoa2V5LCBDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcsIC1kcmF3KSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGxlZnRfam9pbihuZXdfZGF0YSwgYnkgPSAia2V5IikgJT4lIAogIHNlbGVjdCgta2V5KSAlPiUgCiAgICBtdXRhdGUoVHJlYXRtZW50ID0gY2FzZV93aGVuKAogICAgVHJlYXRtZW50ID09ICJGZW1hbGUiIH4gIkZlbWFsZS1saW1pdGVkIiwKICAgIFRyZWF0bWVudCA9PSAiTWFsZSIgfiAiTWFsZS1saW1pdGVkIiwKICAgIFRyZWF0bWVudCA9PSAiQ29udHJvbCIgfiAiQ29udHJvbCIpKQoKcHJlZHNfc3VtbWFyeSA8LQogIHByZWRzICU+JSAKICBncm91cF9ieShUcmVhdG1lbnQsIEdlbmVyYXRpb24sIEJsb2NrKSAlPiUKICBtZWRpYW5fcWkoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nLCAud2lkdGggPSAwLjUpCgpubF9wMSA8LQogIFByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuICU+JSAKICBmaWx0ZXIoQmxvY2sgPT0gMSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBHZW5lcmF0aW9uLCB5ID0gQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nKSkgKwogIGdlb21faml0dGVyKGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbMl0sIHdpZHRoID0gMC4yNSwgCiAgICAgICAgICAgICAgc2hhcGUgPSAxLjUsIHN0cm9rZSA9Miwgc2l6ZSA9IDEuMiwgYWxwaGEgPSAwLjIpICsKICMgZ2VvbV9zbW9vdGgoc2l6ZSA9IDEuNSwgY29sb3VyID0gbWV0LmJyZXdlcigiT0tlZWZmZTIiKVs3XSwgYWxwaGEgPSAwLjQpICsKICBnZW9tX3JpYmJvbihkYXRhID0gcHJlZHNfc3VtbWFyeSAlPiUgZmlsdGVyKEJsb2NrID09ICIxIiksIAogICAgICAgICAgICAgYWVzKHltaW4gPSAubG93ZXIsIHltYXggPSAudXBwZXIsIGZpbGwgPSBUcmVhdG1lbnQpLCBhbHBoYSA9IDEvMikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBUcmVhdG1lbnQsIGNvbG91ciA9IFRyZWF0bWVudCksIGRhdGEgPSBwcmVkc19zdW1tYXJ5ICU+JSBmaWx0ZXIoQmxvY2sgPT0gMSksCiAgICAgICAgICAgIHNpemUgPSAxLCBhbHBoYSA9IDEsIGxpbmV0eXBlID0gNSkgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXMgPSBjKDEsIDIsIDMpKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSwgZ3VpZGUgPSAibm9uZSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSkgKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wMSwgMCkpKSArCiAgdGhlbWVfdGlkeWJheWVzKCkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygxLCAyMCksIHlsaW0gPSBjKDAsIDE1MCkpICsKICBsYWJzKHkgPSAiTGluZWFnZSBwcm9kdWN0aXZpdHkiLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIsIGZpbGwgPSAiU2VsZWN0aW9uIHJlc3BvbnNlXG5oaXN0b3J5IikgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoLjk5LCAuOTkpLAogICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygicmlnaHQiLCAidG9wIiksCiAgICAgICAgbGVnZW5kLmJveC5qdXN0ID0gInJpZ2h0IiwKICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKDYsIDYsIDYsIDYpKQoKbmxfcDIgPC0KICBQcm9kdWN0aXZpdHlfZGF0YV9jbGVhbiAlPiUgZmlsdGVyKEJsb2NrID09IDIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBHZW5lcmF0aW9uLCB5ID0gQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nKSkgKwogIGdlb21faml0dGVyKGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbMl0sIHdpZHRoID0gMC4yNSwgCiAgICAgICAgICAgICAgc2hhcGUgPSAxLjUsIHN0cm9rZSA9Miwgc2l6ZSA9IDEuMiwgYWxwaGEgPSAwLjIpICsKICAjIGdlb21fc21vb3RoKHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbN10sIGFscGhhID0gMC40KSArCiAgZ2VvbV9yaWJib24oZGF0YSA9IHByZWRzX3N1bW1hcnkgJT4lIGZpbHRlcihCbG9jayA9PSAyKSwgCiAgICAgICAgICAgICAgYWVzKHltaW4gPSAubG93ZXIsIHltYXggPSAudXBwZXIsIGZpbGwgPSBUcmVhdG1lbnQpLCBhbHBoYSA9IDEvMikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBUcmVhdG1lbnQsIGNvbG91ciA9IFRyZWF0bWVudCksIGRhdGEgPSBwcmVkc19zdW1tYXJ5ICU+JSBmaWx0ZXIoQmxvY2sgPT0gMiksCiAgICAgICAgICAgIHNpemUgPSAxLCBhbHBoYSA9IDEsIGxpbmV0eXBlID0gNSkgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXMgPSBjKDEsIDIsIDMpKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSwgZ3VpZGUgPSAibm9uZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMDEsIDApKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDMpKSArCiAgdGhlbWVfdGlkeWJheWVzKCkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygxLCAyMCksIHlsaW0gPSBjKDAsIDE1MCkpICsKICBsYWJzKHkgPSAiTGluZWFnZSBwcm9kdWN0aXZpdHkiLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIsIHN1YnRpdGxlID0gIkJsb2NrIDIiLCBmaWxsID0gIlNlbGVjdGlvbiByZXNwb25zZVxuaGlzdG9yeSIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKC45OSwgLjk5KSwKICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoInJpZ2h0IiwgInRvcCIpLAogICAgICAgIGxlZ2VuZC5ib3guanVzdCA9ICJyaWdodCIsCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbig2LCA2LCA2LCA2KSkKCmBgYAoKJH4kCgpFc3RpbWF0aW5nICRhJCBhbmQgJFxsYW1iZGEkIAoKYGBge3J9CgpJbml0aWFsX3Byb2R1Y3Rpdml0eV9lc3RpbWF0ZXMgPC0KYXNfZHJhd3NfZGYobm9ubGluZWFyX3Byb2R1Y3Rpdml0eSwgdmFyaWFibGUgPSAiXmJfYSIsIHJlZ2V4ID0gVFJVRSkgJT4lIAogIG11dGF0ZShgRmVtYWxlLWxpbWl0ZWQgQjFgID0gYl9hX1RyZWF0bWVudEZlbWFsZSwKICAgICAgICAgYE1hbGUtbGltaXRlZCBCMWAgPSBiX2FfVHJlYXRtZW50TWFsZSwKICAgICAgICAgYENvbnRyb2wgQjFgID0gYl9hX1RyZWF0bWVudENvbnRyb2wsCiAgICAgICAgIGBGZW1hbGUtbGltaXRlZCBCMmAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICsgYl9hX0Jsb2NrMiArIGBiX2FfVHJlYXRtZW50RmVtYWxlOkJsb2NrMmAsCiAgICAgICAgIGBNYWxlLWxpbWl0ZWQgQjJgID0gYl9hX1RyZWF0bWVudE1hbGUgKyBiX2FfQmxvY2syICsgYGJfYV9UcmVhdG1lbnRNYWxlOkJsb2NrMmAsCiAgICAgICAgIGBDb250cm9sIEIyYCA9IGJfYV9UcmVhdG1lbnRDb250cm9sICsgYl9hX0Jsb2NrMikgJT4lCiAgc2VsZWN0KGBGZW1hbGUtbGltaXRlZCBCMWAsIGBNYWxlLWxpbWl0ZWQgQjFgLCBgQ29udHJvbCBCMWAsCiAgICAgICAgIGBGZW1hbGUtbGltaXRlZCBCMmAsIGBNYWxlLWxpbWl0ZWQgQjJgLCBgQ29udHJvbCBCMmApICU+JSAKICBtdXRhdGVfYWxsKH4gZXhwKC54KSkgJT4lIAogIG11dGF0ZShwb3N0ZXJpb3Jfc2FtcGxlID0gMTpuKCkpICU+JSAKICBnYXRoZXIoRXZvbHV0aW9uX3RyZWF0bWVudCwgYSwgLXBvc3Rlcmlvcl9zYW1wbGUpICU+JSAKICBzZXBhcmF0ZShjb2wgPSBFdm9sdXRpb25fdHJlYXRtZW50LCBzZXAgPSAiICIsIGludG8gPSBjKCJFdm9sdXRpb25fdHJlYXRtZW50IiwgIkJsb2NrIikpCiAgCgpJbml0aWFsX3Byb2R1Y3Rpdml0eV9wbG90X0IxIDwtCiAgSW5pdGlhbF9wcm9kdWN0aXZpdHlfZXN0aW1hdGVzICU+JSAKICBmaWx0ZXIoQmxvY2sgPT0gIkIxIikgJT4lCiAgCiAgZ2dwbG90KGFlcyh4ID0gYSwgeSA9IEV2b2x1dGlvbl90cmVhdG1lbnQpKSArCiAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gRXZvbHV0aW9uX3RyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBzbGFiX2NvbG91ciA9ICJibGFjayIsIHNsYWJfc2l6ZSA9IDAuOCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyg1MCwgMTUwKSkgKwogIGxhYnMoeD1leHByZXNzaW9uKHBhc3RlKCJJbml0aWFsIHByb2R1Y3Rpdml0eSBwYXJhbWV0ZXIgIixpdGFsaWMoImEiKSkpLCB5ID0gIlNlbGVjdGlvbiByZXNwb25zZSBoaXN0b3J5IikgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcsIGNvbG9yPU5BKSwgI3RyYW5zcGFyZW50IHBsb3QgYmcKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAjdHJhbnNwYXJlbnQgbGVnZW5kIHBhbmVsCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCgpJbml0aWFsX3Byb2R1Y3Rpdml0eV9wbG90X0IyIDwtCiAgSW5pdGlhbF9wcm9kdWN0aXZpdHlfZXN0aW1hdGVzICU+JSAKICBmaWx0ZXIoQmxvY2sgPT0gIkIyIikgJT4lCiAgCiAgZ2dwbG90KGFlcyh4ID0gYSwgeSA9IEV2b2x1dGlvbl90cmVhdG1lbnQpKSArCiAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gRXZvbHV0aW9uX3RyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBzbGFiX2NvbG91ciA9ICJibGFjayIsIHNsYWJfc2l6ZSA9IDAuOCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDUpKSArCiAgbGFicyh4PWV4cHJlc3Npb24ocGFzdGUoIkluaXRpYWwgcHJvZHVjdGl2aXR5IHBhcmFtZXRlciAiLGl0YWxpYygiYSIpKSksIHkgPSAiU2VsZWN0aW9uIHJlc3BvbnNlIGhpc3RvcnkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKCmRlY2F5X2VzdGltYXRlcyA8LSAgCiAgYXNfZHJhd3NfZGYobm9ubGluZWFyX3Byb2R1Y3Rpdml0eSwgdmFyaWFibGUgPSAiXmJfbGFtYmRhIiwgcmVnZXggPSBUUlVFKSAlPiUgCiAgbXV0YXRlKGBGZW1hbGUtbGltaXRlZCBCMWAgPSBiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUsCiAgICAgICAgIGBNYWxlLWxpbWl0ZWQgQjFgID0gYl9sYW1iZGFfVHJlYXRtZW50TWFsZSwKICAgICAgICAgYENvbnRyb2wgQjFgID0gYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCwKICAgICAgICAgYEZlbWFsZS1saW1pdGVkIEIyYCA9IGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSArIGJfbGFtYmRhX0Jsb2NrMiArIGBiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGU6QmxvY2syYCwKICAgICAgICAgYE1hbGUtbGltaXRlZCBCMmAgPSBiX2xhbWJkYV9UcmVhdG1lbnRNYWxlICsgYl9sYW1iZGFfQmxvY2syICsgYGJfbGFtYmRhX1RyZWF0bWVudE1hbGU6QmxvY2syYCwKICAgICAgICAgYENvbnRyb2wgQjJgID0gYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCArIGJfbGFtYmRhX0Jsb2NrMikgJT4lCiBzZWxlY3QoYEZlbWFsZS1saW1pdGVkIEIxYCwgYE1hbGUtbGltaXRlZCBCMWAsIGBDb250cm9sIEIxYCwKICAgICAgICAgYEZlbWFsZS1saW1pdGVkIEIyYCwgYE1hbGUtbGltaXRlZCBCMmAsIGBDb250cm9sIEIyYCkgJT4lIAogIG11dGF0ZShwb3N0ZXJpb3Jfc2FtcGxlID0gMTpuKCkpICU+JSAKICBnYXRoZXIoRXZvbHV0aW9uX3RyZWF0bWVudCwgbGFtYmRhLCAtcG9zdGVyaW9yX3NhbXBsZSkgJT4lCiAgc2VwYXJhdGUoY29sID0gRXZvbHV0aW9uX3RyZWF0bWVudCwgc2VwID0gIiAiLCBpbnRvID0gYygiRXZvbHV0aW9uX3RyZWF0bWVudCIsICJCbG9jayIpKQogIAoKZGVjYXlfcGxvdF9CMSA8LQogIGRlY2F5X2VzdGltYXRlcyAlPiUgCiAgZmlsdGVyKEJsb2NrID09ICJCMSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBsYW1iZGEsIHkgPSBFdm9sdXRpb25fdHJlYXRtZW50KSkgKwogICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gRXZvbHV0aW9uX3RyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLCAKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgc2xhYl9jb2xvdXIgPSAiYmxhY2siLCBzbGFiX3NpemUgPSAwLjgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGxhYnMoeD1leHByZXNzaW9uKHBhc3RlKCJEZWNheSByYXRlIHBhcmFtZXRlciAiLCBsYW1iZGEsKSksIHkgPSAiU2VsZWN0aW9uIHJlc3BvbnNlIGhpc3RvcnkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKZGVjYXlfcGxvdF9CMiA8LQogIGRlY2F5X2VzdGltYXRlcyAlPiUgCiAgZmlsdGVyKEJsb2NrID09ICJCMiIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBsYW1iZGEsIHkgPSBFdm9sdXRpb25fdHJlYXRtZW50KSkgKwogICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gRXZvbHV0aW9uX3RyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBzbGFiX2NvbG91ciA9ICJibGFjayIsIHNsYWJfc2l6ZSA9IDAuOCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDUpKSArCiAgbGFicyh4PWV4cHJlc3Npb24ocGFzdGUoIkRlY2F5IHJhdGUgcGFyYW1ldGVyICIsIGxhbWJkYSwpKSwgeSA9ICJTZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yeSIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcpLCAjdHJhbnNwYXJlbnQgcGFuZWwgYmcKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvcj1OQSksICN0cmFuc3BhcmVudCBwbG90IGJnCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgpgYGAKCkNyZWF0ZSBsZWFmIHBsb3RzIGxpa2UgdGhvc2UgaW4gRmlndXJlIDEKCmBgYHtyfQpwcm9kdWN0aXZpdHlfY3VydmUgPC0KICBub25saW5lYXJfcHJvZHVjdGl2aXR5ICU+JSAKICBhc19kcmF3c19kZigpICU+JSAKICBzZWxlY3QoY29udGFpbnMoImJfIikpICU+JSAKICBtdXRhdGUoYWNyb3NzKDE6MywgfiBleHAoLngpKSwKICAgICAgICAgQ29udHJvbF8wICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMCksCiAgICAgICAgIENvbnRyb2xfMSAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wpKjEpLAogICAgICAgICBDb250cm9sXzIgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoyKSwKICAgICAgICAgQ29udHJvbF8zICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMyksCiAgICAgICAgIENvbnRyb2xfNCAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wpKjQpLAogICAgICAgICBDb250cm9sXzUgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSo1KSwKICAgICAgICAgQ29udHJvbF82ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqNiksCiAgICAgICAgIENvbnRyb2xfNyAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wpKjcpLAogICAgICAgICBDb250cm9sXzggID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSo4KSwKICAgICAgICAgQ29udHJvbF85ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqOSksCiAgICAgICAgIENvbnRyb2xfMTAgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxMCksCiAgICAgICAgIENvbnRyb2xfMTEgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxMSksCiAgICAgICAgIENvbnRyb2xfMTIgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxMiksCiAgICAgICAgIENvbnRyb2xfMTMgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxMyksCiAgICAgICAgIENvbnRyb2xfMTQgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxNCksCiAgICAgICAgIENvbnRyb2xfMTUgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxNSksCiAgICAgICAgIENvbnRyb2xfMTYgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxNiksCiAgICAgICAgIENvbnRyb2xfMTcgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxNyksCiAgICAgICAgIENvbnRyb2xfMTggID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxOCksCiAgICAgICAgIENvbnRyb2xfMTkgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxOSksCiAgICAgICAgIENvbnRyb2xfMjAgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoyMCksCiAgICAgICAgIEZlbWFsZV8wICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjApLAogICAgICAgICBGZW1hbGVfMSAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlKSoxKSwKICAgICAgICAgRmVtYWxlXzIgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMiksCiAgICAgICAgIEZlbWFsZV8zICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjMpLAogICAgICAgICBGZW1hbGVfNCAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlKSo0KSwKICAgICAgICAgRmVtYWxlXzUgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqNSksCiAgICAgICAgIEZlbWFsZV82ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjYpLAogICAgICAgICBGZW1hbGVfNyAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlKSo3KSwKICAgICAgICAgRmVtYWxlXzggID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqOCksCiAgICAgICAgIEZlbWFsZV85ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjkpLAogICAgICAgICBGZW1hbGVfMTAgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTApLAogICAgICAgICBGZW1hbGVfMTEgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTEpLAogICAgICAgICBGZW1hbGVfMTIgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTIpLAogICAgICAgICBGZW1hbGVfMTMgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTMpLAogICAgICAgICBGZW1hbGVfMTQgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTQpLAogICAgICAgICBGZW1hbGVfMTUgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTUpLAogICAgICAgICBGZW1hbGVfMTYgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTYpLAogICAgICAgICBGZW1hbGVfMTcgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTcpLAogICAgICAgICBGZW1hbGVfMTggID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTgpLAogICAgICAgICBGZW1hbGVfMTkgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMTkpLAogICAgICAgICBGZW1hbGVfMjAgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMjApLAogICAgICAgICBNYWxlXzAgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSowKSwKICAgICAgICAgTWFsZV8xICA9IGJfYV9UcmVhdG1lbnRNYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50TWFsZSkqMSksCiAgICAgICAgIE1hbGVfMiAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjIpLAogICAgICAgICBNYWxlXzMgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSozKSwKICAgICAgICAgTWFsZV80ICA9IGJfYV9UcmVhdG1lbnRNYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50TWFsZSkqNCksCiAgICAgICAgIE1hbGVfNSAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjUpLAogICAgICAgICBNYWxlXzYgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSo2KSwKICAgICAgICAgTWFsZV83ICA9IGJfYV9UcmVhdG1lbnRNYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50TWFsZSkqNyksCiAgICAgICAgIE1hbGVfOCAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjgpLAogICAgICAgICBNYWxlXzkgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSo5KSwKICAgICAgICAgTWFsZV8xMCAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjEwKSwKICAgICAgICAgTWFsZV8xMSAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjExKSwKICAgICAgICAgTWFsZV8xMiAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjEyKSwKICAgICAgICAgTWFsZV8xMyAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjEzKSwKICAgICAgICAgTWFsZV8xNCAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjE0KSwKICAgICAgICAgTWFsZV8xNSAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjE1KSwKICAgICAgICAgTWFsZV8xNiAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjE2KSwKICAgICAgICAgTWFsZV8xNyAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjE3KSwKICAgICAgICAgTWFsZV8xOCAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjE4KSwKICAgICAgICAgTWFsZV8xOSAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjE5KSwKICAgICAgICAgTWFsZV8yMCAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjIwKSkgJT4lIAogIHNlbGVjdCgtYyhjb250YWlucygiYl8iKSkpCgpEaWZmZXJlbmNlX2dlbnNfcHJvZHVjdGl2aXR5IDwtIAogIHByZWRzICU+JSAKICBncm91cF9ieShHZW5lcmF0aW9uLCBUcmVhdG1lbnQsIEJsb2NrKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBwaXZvdF93aWRlcih2YWx1ZXNfZnJvbSA9ICJDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmciLCBuYW1lc19mcm9tID0gIlRyZWF0bWVudCIpICU+JSAKICBtdXRhdGUoZGlmZi5tYyA9IGBNYWxlLWxpbWl0ZWRgIC0gQ29udHJvbCwKICAgICAgICAgZGlmZi5tZiA9IGBNYWxlLWxpbWl0ZWRgIC0gYEZlbWFsZS1saW1pdGVkYCwKICAgICAgICAgZGlmZi5mYyA9IGBGZW1hbGUtbGltaXRlZGAgLSBDb250cm9sKSAlPiUgCiAgc2VsZWN0KEdlbmVyYXRpb24sIEJsb2NrLCBjb250YWlucygiZGlmZiIpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjb250YWlucygiZGlmZiIpLCB2YWx1ZXNfdG8gPSAic3Vydml2YWxfZGlmZiIsIG5hbWVzX3RvID0gIkRpZmZlcmVuY2UgY29udHJhc3QiKSAKCiMgTWFrZSB0aGUgdGhyZWUgcGxvdHMKCkxlYWZfcGxvdF9tY19wcm9kdWN0aXZpdHlfQjEgPC0KICBEaWZmZXJlbmNlX2dlbnNfcHJvZHVjdGl2aXR5ICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYubWMiICYgQmxvY2sgPT0gIjEiKSAlPiUgCiAgZ2dwbG90KGFlcyhzdXJ2aXZhbF9kaWZmLCBhcy5mYWN0b3IoR2VuZXJhdGlvbikpKSArCiAgc3RhdF9pbnRlcnZhbCgud2lkdGggPSBjKDAuMDUsIDAuNjYsIDAuOTUpLCAKICAgICAgICAgICAgICAgIGhlaWdodCA9IDEsIHNob3cubGVnZW5kID0gRikgKwogIHJjYXJ0b2NvbG9yOjpzY2FsZV9jb2xvcl9jYXJ0b19kKHBhbGV0dGUgPSAiUHVycCIpICsKICAjY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIk1hbGUgLSBDb250cm9sXG5Qcm9kdWN0aXZpdHkgZGlmZi4iLAogICAgICAgeSA9ICJHZW5lcmF0aW9uIG9mIGluYnJlZWRpbmciKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKTGVhZl9wbG90X21jX3Byb2R1Y3Rpdml0eV9CMiA8LQogIERpZmZlcmVuY2VfZ2Vuc19wcm9kdWN0aXZpdHkgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5tYyIgJiBCbG9jayA9PSAiMiIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJQdXJwIikgKwogICNjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTAuMSwgMC4zKSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPXJldikgKwogIGdlb21fdmxpbmUobGluZXR5cGUgPSAyLCB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDEpICsKICBsYWJzKHggPSAiTWFsZSAtIENvbnRyb2xcblByb2R1Y3Rpdml0eSBkaWZmLiIsCiAgICAgICB5ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgpMZWFmX3Bsb3RfbWZfcHJvZHVjdGl2aXR5X0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX3Byb2R1Y3Rpdml0eSAlPiUKICBmaWx0ZXIoYERpZmZlcmVuY2UgY29udHJhc3RgID09ICJkaWZmLm1mIiAmIEJsb2NrID09ICIxIikgJT4lIAogIGdncGxvdChhZXMoc3Vydml2YWxfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlRlYWxHcm4iKSArCiAgI2Nvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJNYWxlIC0gRmVtYWxlXG5Qcm9kdWN0aXZpdHkgZGlmZi4iLAogICAgICAgeSA9IE5VTEwpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgpMZWFmX3Bsb3RfbWZfcHJvZHVjdGl2aXR5X0IyIDwtCiAgRGlmZmVyZW5jZV9nZW5zX3Byb2R1Y3Rpdml0eSAlPiUKICBmaWx0ZXIoYERpZmZlcmVuY2UgY29udHJhc3RgID09ICJkaWZmLm1mIiAmIEJsb2NrID09ICIyIikgJT4lIAogIGdncGxvdChhZXMoc3Vydml2YWxfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlRlYWxHcm4iKSArCiAgI2Nvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJNYWxlIC0gRmVtYWxlXG5Qcm9kdWN0aXZpdHkgZGlmZi4iLAogICAgICAgeSA9IE5VTEwpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgpMZWFmX3Bsb3RfZmNfcHJvZHVjdGl2aXR5X0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX3Byb2R1Y3Rpdml0eSAlPiUKICBmaWx0ZXIoYERpZmZlcmVuY2UgY29udHJhc3RgID09ICJkaWZmLmZjIiAmIEJsb2NrID09ICIxIikgJT4lIAogIGdncGxvdChhZXMoc3Vydml2YWxfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlBlYWNoIikgKwogICNjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTAuMSwgMC4zKSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPXJldikgKwogIGdlb21fdmxpbmUobGluZXR5cGUgPSAyLCB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDEpICsKICBsYWJzKHggPSAiRmVtYWxlIC0gQ29udHJvbFxuUHJvZHVjdGl2aXR5IGRpZmYuIiwKICAgICAgIHkgPSBOVUxMKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKTGVhZl9wbG90X2ZjX3Byb2R1Y3Rpdml0eV9CMiA8LQogIERpZmZlcmVuY2VfZ2Vuc19wcm9kdWN0aXZpdHkgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5mYyIgJiBCbG9jayA9PSAiMiIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJQZWFjaCIpICsKICAjY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIkZlbWFsZSAtIENvbnRyb2xcblByb2R1Y3Rpdml0eSBkaWZmLiIsCiAgICAgICB5ID0gTlVMTCkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkKCmBgYAoKIyMjIEZpZ3VyZSAyIGFuZCBGaWd1cmUgU1gKCmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTB9CihubF9wMSAvIChJbml0aWFsX3Byb2R1Y3Rpdml0eV9wbG90X0IxICsgZGVjYXlfcGxvdF9CMSkpIC8gKExlYWZfcGxvdF9tY19wcm9kdWN0aXZpdHlfQjEgKyBMZWFmX3Bsb3RfbWZfcHJvZHVjdGl2aXR5X0IxICsgTGVhZl9wbG90X2ZjX3Byb2R1Y3Rpdml0eV9CMSkgKwogIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gJ2EnKQpgYGAKCioqRmlndXJlIDIqKi4gdGhlIGZpZ3VyZSB0byBlbmQgYWxsIGZpZ3VyZXMgYWdhaW4uIEJsb2NrIDEKCiR+JAoKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMH0KKG5sX3AyIC8gKEluaXRpYWxfcHJvZHVjdGl2aXR5X3Bsb3RfQjIgKyBkZWNheV9wbG90X0IyKSkgLyAoTGVhZl9wbG90X21jX3Byb2R1Y3Rpdml0eV9CMiArIExlYWZfcGxvdF9tZl9wcm9kdWN0aXZpdHlfQjIgKyBMZWFmX3Bsb3RfZmNfcHJvZHVjdGl2aXR5X0IyKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAnYScpCmBgYAoKKipGaWd1cmUgU1gqKi4gdGhlIGZpZ3VyZSB0byBlbmQgYWxsIGZpZ3VyZXMgYWdhaW4uIEJsb2NrIDIKCgo=